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