]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/nextid.c
0e45fced41691d42fe1ac8e822475b65827346d5
[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 /* All functions except put_nextid() obey slapMode == SLAP_TOOL_MODE. */
21
22 static ID  next_id_read( Backend *be );
23 static ID  next_id_get_save( Backend *be, int do_save );
24
25 #define    next_id_write( be, id ) \
26         (slapMode == SLAP_TOOL_MODE ? (be, id, 0) : put_nextid( be, id ))
27
28 static ID
29 next_id_read( Backend *be )
30 {
31         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
32         ID      id;
33         char    buf[20];
34         char*   file = li->li_nextid_file; 
35         FILE*   fp;
36
37         if ( slapMode == SLAP_TOOL_MODE )
38                 return NOID;
39
40         if ( (fp = fopen( file, "r" )) == NULL ) {
41                 Debug( LDAP_DEBUG_ANY,
42                     "next_id_read: could not open \"%s\"\n",
43                     file, 0, 0 );
44                 return NOID;
45         }
46
47         if ( fgets( buf, sizeof(buf), fp ) == NULL ) {
48                 Debug( LDAP_DEBUG_ANY,
49                    "next_id_read: could not fgets nextid from \"%s\"\n",
50                     file, 0, 0 );
51                 fclose( fp );
52                 return NOID;
53         }
54
55         id = atol( buf );
56         fclose( fp );
57
58         if(id < 1) {
59                 Debug( LDAP_DEBUG_ANY,
60                         "next_id_read %ld: atol(%s) return non-positive integer\n",
61                         id, buf, 0 );
62                 return NOID;
63         }
64
65         return id;
66 }
67
68 int
69 put_nextid( Backend *be, ID id )
70 {
71         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
72         char*   file = li->li_nextid_file; 
73         FILE*   fp;
74         int             rc;
75
76         if ( (fp = fopen( file, "w" )) == NULL ) {
77                 Debug( LDAP_DEBUG_ANY, "put_nextid(%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, "put_nextid(%ld): cannot fprintf\n",
86                     id, 0, 0 );
87                 rc = -1;
88         }
89
90         if( fclose( fp ) != 0 ) {
91                 Debug( LDAP_DEBUG_ANY, "put_nextid %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 }