ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
}
- e->e_id = next_id( be );
-
- if( e->e_id == NOID ) {
+ if ( next_id( be, &e->e_id ) ) {
if( p != NULL) {
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
Debug( LDAP_DEBUG_TRACE, "index_entry_add failed\n", 0,
0, 0 );
#endif
-
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "index generation failed", NULL, NULL );
Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0,
0, 0 );
#endif
+ /* FIXME: delete attr indices? */
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "DN index generation failed", NULL, NULL );
0, 0 );
#endif
+ /* FIXME: delete attr indices? */
(void) dn2id_delete( be, e->e_ndn, e->e_id );
+
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "entry store failed", NULL, NULL );
}
if ( rc ) {
+ /* FIXME: remove from cache? */
+ cache_entry_private_destroy_mark( e );
+
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
}
#define CACHE_ENTRY_CREATING 1
#define CACHE_ENTRY_READY 2
#define CACHE_ENTRY_DELETED 3
-
+#define CACHE_ENTRY_DESTROY_PRIVATE 4
+
int lei_refcnt; /* # threads ref'ing this entry */
Entry *lei_lrunext; /* for cache lru list */
Entry *lei_lruprev;
return 0;
}
+/*
+ * assumes that the entry is write-locked;marks it i a manner that
+ * makes e_private be destroyed at the following cache_return_entry_w,
+ * but lets the entry untouched (owned by someone else)
+ */
+void
+cache_entry_private_destroy_mark( Entry *e )
+{
+ assert( e );
+ assert( e->e_private );
+
+ LEI(e)->lei_state = CACHE_ENTRY_DESTROY_PRIVATE;
+}
+
static int
cache_entry_private_destroy( Entry*e )
{
#endif
- } else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) {
+ } else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED
+ || LEI(e)->lei_state == CACHE_ENTRY_DESTROY_PRIVATE ) {
if( refcnt > 0 ) {
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
} else {
+ int state = LEI(e)->lei_state;
+
cache_entry_private_destroy( e );
- entry_free( e );
+ if ( state == CACHE_ENTRY_DELETED ) {
+ entry_free( e );
+ }
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
idl_allids( Backend *be )
{
ID_BLOCK *idl;
+ ID id;
idl = idl_alloc( 0 );
ID_BLOCK_NMAX(idl) = ID_BLOCK_ALLIDS_VALUE;
- ID_BLOCK_NIDS(idl) = next_id_get( be );
+ if ( next_id_get( be, &id ) ) {
+ return NULL;
+ }
+ ID_BLOCK_NIDS(idl) = id;
return( idl );
}
#include "slap.h"
#include "back-ldbm.h"
-static ID
-next_id_read( Backend *be )
+static int
+next_id_read( Backend *be, ID *idp )
{
- ID id = NOID;
Datum key, data;
DBCache *db;
+ *idp = NOID;
+
if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
#ifdef NEW_LOGGING
0, 0, 0 );
#endif
- return( NOID );
+ return( -1 );
}
ldbm_datum_init( key );
- key.dptr = (char *) &id;
+ key.dptr = (char *) idp;
key.dsize = sizeof(ID);
data = ldbm_cache_fetch( db, key );
if( data.dptr != NULL ) {
- AC_MEMCPY( &id, data.dptr, sizeof( ID ) );
+ AC_MEMCPY( idp, data.dptr, sizeof( ID ) );
ldbm_datum_free( db->dbc_db, data );
} else {
- id = 1;
+ *idp = 1;
}
ldbm_cache_close( be, db );
- return id;
+ return( 0 );
}
-ID
+int
next_id_write( Backend *be, ID id )
{
- struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Datum key, data;
DBCache *db;
ID noid = NOID;
- int flags;
+ int flags, rc = 0;
if ( (db = ldbm_cache_open( be, "nextid", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
0, 0, 0 );
#endif
- return( NOID );
+ return( -1 );
}
ldbm_datum_init( key );
flags = LDBM_REPLACE;
if ( ldbm_cache_store( db, key, data, flags ) != 0 ) {
- id = NOID;
+ rc = -1;
}
ldbm_cache_close( be, db );
- return id;
+ return( rc );
}
-ID
-next_id_get( Backend *be )
+int
+next_id_get( Backend *be, ID *idp )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- ID id = NOID;
+ int rc = 0;
+
+ *idp = NOID;
ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
if ( li->li_nextid == NOID ) {
- li->li_nextid = next_id_read( be );
+ if ( ( rc = next_id_read( be, idp ) ) ) {
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
+ return( rc );
+ }
+ li->li_nextid = *idp;
}
- id = li->li_nextid;
+ *idp = li->li_nextid;
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
- return id;
+ return( rc );
}
-ID
-next_id( Backend *be )
+int
+next_id( Backend *be, ID *idp )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- ID id = NOID;
+ int rc = 0;
ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
if ( li->li_nextid == NOID ) {
- li->li_nextid = next_id_read( be );
+ if ( ( rc = next_id_read( be, idp ) ) ) {
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
+ return( rc );
+ }
+ li->li_nextid = *idp;
}
- if ( li->li_nextid != NOID ) {
- id = li->li_nextid++;
-
- (void) next_id_write( be, li->li_nextid );
+ *idp = li->li_nextid++;
+ if ( next_id_write( be, li->li_nextid ) ) {
+ rc = -1;
}
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
- return id;
+ return( rc );
}
void cache_return_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw ));
#define cache_return_entry_r(c, e) cache_return_entry_rw((c), (e), 0)
#define cache_return_entry_w(c, e) cache_return_entry_rw((c), (e), 1)
+void cache_entry_private_destroy_mark LDAP_P(( Entry *e ));
ID cache_find_entry_dn2id LDAP_P(( Backend *be, Cache *cache, const char *dn ));
ID cache_find_entry_ndn2id LDAP_P(( Backend *be, Cache *cache, const char *ndn ));
* nextid.c
*/
-ID next_id LDAP_P(( Backend *be ));
-ID next_id_get LDAP_P(( Backend *be ));
-ID next_id_write LDAP_P(( Backend *be, ID id ));
+int next_id LDAP_P(( Backend *be, ID *idp ));
+int next_id_get LDAP_P(( Backend *be, ID *idp ));
+int next_id_write LDAP_P(( Backend *be, ID id ));
LDAP_END_DECL
#endif
assert( slapMode & SLAP_TOOL_MODE );
assert( id2entry != NULL );
- if( next_id_get( be ) == NOID ) {
+ if ( next_id_get( be, &id ) || id == NOID ) {
return NOID;
}
assert( slapMode & SLAP_TOOL_MODE );
if ( li->li_nextid != NOID ) {
- next_id_write( be, li->li_nextid );
+ if ( next_id_write( be, li->li_nextid ) ) {
+ return( -1 );
+ }
}
return 0;