]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/nextid.c
594e542a21778ce8930bddb46519519e73518998
[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
17 next_id_read( Backend *be )
18 {
19         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
20         ID      id;
21         char    buf[20];
22         char*   file = li->li_nextid_file; 
23         FILE*   fp;
24
25         if ( (fp = fopen( file, "r" )) == NULL ) {
26                 Debug( LDAP_DEBUG_ANY,
27                     "next_id_read: could not open \"%s\"\n",
28                     file, 0, 0 );
29                 return NOID;
30         }
31
32         if ( fgets( buf, sizeof(buf), fp ) == NULL ) {
33                 Debug( LDAP_DEBUG_ANY,
34                    "next_id_read: could not fgets nextid from \"%s\"\n",
35                     file, 0, 0 );
36                 fclose( fp );
37                 return NOID;
38         }
39
40         id = atol( buf );
41         fclose( fp );
42
43         if(id < 1) {
44                 Debug( LDAP_DEBUG_ANY,
45                         "next_id_read %lu: atol(%s) return non-positive integer\n",
46                         id, buf, 0 );
47                 return NOID;
48         }
49
50         return id;
51 }
52
53 static int
54 next_id_write( Backend *be, ID id )
55 {
56         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
57         char    buf[20];
58         char*   file = li->li_nextid_file; 
59         FILE*   fp;
60         int             rc;
61
62         if ( (fp = fopen( file, "w" )) == NULL ) {
63                 Debug( LDAP_DEBUG_ANY, "next_id_write(%lu): could not open \"%s\"\n",
64                     id, file, 0 );
65                 return -1;
66         } 
67
68         rc = 0;
69
70         if ( fprintf( fp, "%ld\n", id ) == EOF ) {
71                 Debug( LDAP_DEBUG_ANY, "next_id_write(%lu): cannot fprintf\n",
72                     id, 0, 0 );
73                 rc = -1;
74         }
75
76         if( fclose( fp ) != 0 ) {
77                 Debug( LDAP_DEBUG_ANY, "next_id_write %lu: cannot fclose\n",
78                     id, 0, 0 );
79                 rc = -1;
80         }
81
82         return rc;
83 }
84
85 ID
86 next_id( Backend *be )
87 {
88         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
89         ID              id;
90
91         pthread_mutex_lock( &li->li_nextid_mutex );
92
93         /* first time in here since startup - try to read the nexid */
94         if ( li->li_nextid == NOID ) {
95                 li->li_nextid = next_id_read( be );
96
97                 if ( li->li_nextid == NOID ) {
98                         li->li_nextid = 1;
99                 }
100         }
101
102         id = li->li_nextid++;
103         (void) next_id_write( be, li->li_nextid );
104
105         pthread_mutex_unlock( &li->li_nextid_mutex );
106         return( id );
107 }
108
109 void
110 next_id_return( Backend *be, ID id )
111 {
112         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
113
114         pthread_mutex_lock( &li->li_nextid_mutex );
115
116         if ( id != li->li_nextid - 1 ) {
117                 pthread_mutex_unlock( &li->li_nextid_mutex );
118                 return;
119         }
120
121         li->li_nextid--;
122         (void) next_id_write( be, li->li_nextid );
123
124         pthread_mutex_unlock( &li->li_nextid_mutex );
125 }
126
127 ID
128 next_id_get( Backend *be )
129 {
130         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
131         ID              id;
132
133         pthread_mutex_lock( &li->li_nextid_mutex );
134
135         /* first time in here since startup - try to read the nexid */
136         if ( li->li_nextid == NOID ) {
137                 li->li_nextid = next_id_read( be );
138
139                 if ( li->li_nextid == NOID ) {
140                         li->li_nextid = 1;
141                 }
142         }
143
144         id = li->li_nextid;
145
146         pthread_mutex_unlock( &li->li_nextid_mutex );
147
148         return( id );
149 }