]> git.sur5r.net Git - openldap/commitdiff
Reworked API of nextid; e_private gets destroyed separately from the entry in case...
authorPierangelo Masarati <ando@openldap.org>
Fri, 20 Jul 2001 09:50:28 +0000 (09:50 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 20 Jul 2001 09:50:28 +0000 (09:50 +0000)
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/cache.c
servers/slapd/back-ldbm/idl.c
servers/slapd/back-ldbm/nextid.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-ldbm/tools.c

index 5ff80d36b16f11a9331431c7971a34077cb78f43..bd9d7969529b7b19648072ba1b36fb7e6bc36c5b 100644 (file)
@@ -240,9 +240,7 @@ ldbm_back_add(
                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 ); 
@@ -311,7 +309,7 @@ ldbm_back_add(
                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 );
 
@@ -327,6 +325,7 @@ ldbm_back_add(
                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 );
@@ -344,7 +343,9 @@ ldbm_back_add(
                    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 );
 
@@ -367,6 +368,9 @@ return_results:;
        }
 
        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 );
        }
index f87bb405f195e8dd9330d1d0f83b66d49394602e..65c1e4fec24934c9c9f72bb87b266f931837cf88 100644 (file)
@@ -31,7 +31,8 @@ typedef struct ldbm_entry_info {
 #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;
@@ -134,6 +135,20 @@ cache_entry_private_init( Entry*e )
        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 )
 {
@@ -179,7 +194,8 @@ cache_return_entry_rw( Cache *cache, Entry *e, int rw )
 #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 );
@@ -196,8 +212,12 @@ cache_return_entry_rw( Cache *cache, Entry *e, int rw )
 
 
                } 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 );
index a0491cbca7f69d5e8a0001f42de9df936d3a9d14..93c26ed8de46ebb9c406b0e0bc0295956374058e 100644 (file)
@@ -65,10 +65,14 @@ ID_BLOCK    *
 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 );
 }
index 8ac43d944a13627e599f310e2a332f41e8413f73..97772bfcc8dc5a902146e6a545594ee5d5612155 100644 (file)
 #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
@@ -36,35 +37,34 @@ next_id_read( Backend *be )
                        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 ) {
@@ -76,7 +76,7 @@ next_id_write( Backend *be, ID id )
                    0, 0, 0 );
 #endif
 
-               return( NOID );
+               return( -1 );
        }
 
        ldbm_datum_init( key );
@@ -90,49 +90,58 @@ next_id_write( Backend *be, ID id )
 
        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 );
 }
index c6aecfdb95051554b271c662c396acdeb989b0a0..7d798fe55aacaf55bf9901c61f8e6758146ed58a 100644 (file)
@@ -51,6 +51,7 @@ int cache_update_entry LDAP_P(( Cache *cache, Entry *e ));
 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 ));
@@ -213,9 +214,9 @@ int ldbm_modify_internal LDAP_P((Backend *be,
  * 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
index 94d0dc6387d6cf2804a4d3f83d2db30683565865..226db043a6718979b93ef50abfe2bf66ad3f7ac2 100644 (file)
@@ -162,7 +162,7 @@ ID ldbm_tool_entry_put(
        assert( slapMode & SLAP_TOOL_MODE );
        assert( id2entry != NULL );
 
-       if( next_id_get( be ) == NOID ) {
+       if ( next_id_get( be, &id ) || id == NOID ) {
                return NOID;
        }
 
@@ -286,7 +286,9 @@ int ldbm_tool_sync( BackendDB *be )
        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;