]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/nextid.c
d0d259aba85b721b6925585bd16743e5f03adedf
[openldap] / servers / slapd / back-ldbm / nextid.c
1 /* id.c - keep track of the next id to be given out */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/socket.h>
12
13 #ifdef HAVE_SYS_PARAM_H
14 #include <sys/param.h>
15 #endif
16
17 #include "slap.h"
18 #include "back-ldbm.h"
19
20 static ID  next_id_read( Backend *be );
21 static int next_id_write( Backend *be, ID id );
22 static ID  next_id_get_save( Backend *be, int do_save );
23
24
25 static ID
26 next_id_read( Backend *be )
27 {
28         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
29         ID      id;
30         char    buf[20];
31         char*   file = li->li_nextid_file; 
32         FILE*   fp;
33
34         if ( ldbm_ignore_nextid_file )
35                 return NOID;
36
37         if ( (fp = fopen( file, "r" )) == NULL ) {
38                 Debug( LDAP_DEBUG_ANY,
39                     "next_id_read: could not open \"%s\"\n",
40                     file, 0, 0 );
41                 return NOID;
42         }
43
44         if ( fgets( buf, sizeof(buf), fp ) == NULL ) {
45                 Debug( LDAP_DEBUG_ANY,
46                    "next_id_read: could not fgets nextid from \"%s\"\n",
47                     file, 0, 0 );
48                 fclose( fp );
49                 return NOID;
50         }
51
52         id = atol( buf );
53         fclose( fp );
54
55         if(id < 1) {
56                 Debug( LDAP_DEBUG_ANY,
57                         "next_id_read %ld: atol(%s) return non-positive integer\n",
58                         id, buf, 0 );
59                 return NOID;
60         }
61
62         return id;
63 }
64
65 static int
66 next_id_write( Backend *be, ID id )
67 {
68         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
69         char*   file = li->li_nextid_file; 
70         FILE*   fp;
71         int             rc;
72
73         if ( ldbm_ignore_nextid_file )
74                 return 0;
75
76         if ( (fp = fopen( file, "w" )) == NULL ) {
77                 Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): could not open \"%s\"\n",
78                     id, file, 0 );
79                 return -1;
80         } 
81
82         rc = 0;
83
84         if ( fprintf( fp, "%ld\n", id ) == EOF ) {
85                 Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): cannot fprintf\n",
86                     id, 0, 0 );
87                 rc = -1;
88         }
89
90         if( fclose( fp ) != 0 ) {
91                 Debug( LDAP_DEBUG_ANY, "next_id_write %ld: cannot fclose\n",
92                     id, 0, 0 );
93                 rc = -1;
94         }
95
96         return rc;
97 }
98
99 int
100 next_id_save( Backend *be )
101 {
102         return( next_id_get_save( be, 1 ) == NOID ? -1 : 0 );
103 }
104
105 ID
106 next_id( Backend *be )
107 {
108         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
109         ID              id;
110
111         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
112
113         /* first time in here since startup - try to read the nexid */
114         if ( li->li_nextid == NOID ) {
115                 li->li_nextid = next_id_read( be );
116
117                 if ( li->li_nextid == NOID ) {
118                         li->li_nextid = 1;
119                 }
120
121 #if SLAPD_NEXTID_CHUNK > 1
122                 li->li_nextid_wrote = li->li_nextid;
123 #endif
124         }
125
126         id = li->li_nextid++;
127
128 #if SLAPD_NEXTID_CHUNK > 1
129         if ( li->li_nextid > li->li_nextid_wrote ) {
130                 li->li_nextid_wrote += SLAPD_NEXTID_CHUNK;
131                 (void) next_id_write( be, li->li_nextid_wrote );
132         }
133 #else
134         (void) next_id_write( be, li->li_nextid );
135 #endif
136
137         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
138         return( id );
139 }
140
141 void
142 next_id_return( Backend *be, ID id )
143 {
144 #ifdef SLAPD_NEXTID_RETURN
145         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
146
147         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
148
149         if ( id != li->li_nextid - 1 ) {
150                 ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
151                 return;
152         }
153
154         li->li_nextid--;
155
156 #if !( SLAPD_NEXTID_CHUNK > 1 )
157         (void) next_id_write( be, li->li_nextid );
158 #endif
159
160         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
161 #endif
162 }
163
164 ID
165 next_id_get( Backend *be )
166 {
167         return next_id_get_save( be, 0 );
168 }
169
170 static ID
171 next_id_get_save( Backend *be, int do_save )
172 {
173         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
174         ID              id;
175
176         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
177
178         /* first time in here since startup - try to read the nexid */
179         if ( li->li_nextid == NOID ) {
180                 li->li_nextid = next_id_read( be );
181
182                 if ( li->li_nextid == NOID ) {
183                         li->li_nextid = 1;
184                 }
185
186 #if SLAPD_NEXTID_CHUNK > 1
187                 li->li_nextid_wrote = li->li_nextid;
188 #endif
189         }
190
191         id = li->li_nextid;
192
193         if ( do_save ) {
194                 if ( next_id_write( be, id ) == 0 ) {
195                         li->li_nextid_wrote = id;
196                 } else {
197                         id = NOID;
198                 }
199         }
200
201         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
202
203         return( id );
204 }