From ecdf9a354dd9e9b1438530a039e9f40bec4e5e6c Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 22 Jan 1999 00:27:50 +0000 Subject: [PATCH] Entry must be locked before adding it to the cache. This removes a race condition upon the entry. --- servers/slapd/back-ldbm/add.c | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index fbf31f43b4..8e8316c196 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -123,13 +123,34 @@ ldbm_back_add( pthread_mutex_unlock(&li->li_add_mutex); } + /* acquire required reader/writer lock */ + if (entry_rdwr_lock(e, 1)) { + if( p != NULL) { + /* free parent and writer lock */ + cache_return_entry_w( &li->li_cache, p ); + } + + if ( rootlock ) { + /* release root lock */ + pthread_mutex_unlock(&li->li_root_mutex); + } + + Debug( LDAP_DEBUG_ANY, "add: could not lock entry\n", + 0, 0, 0 ); + + entry_free(e); + + send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" ); + return( -1 ); + } + + e->e_id = next_id( be ); + /* - * Try to add the entry to the cache, assign it a new dnid - * and mark it locked. This should only fail if the entry - * already exists. + * Try to add the entry to the cache, assign it a new dnid. + * This should only fail if the entry already exists. */ - e->e_id = next_id( be ); if ( cache_add_entry_lock( &li->li_cache, e, ENTRY_STATE_CREATING ) != 0 ) { if( p != NULL) { /* free parent and writer lock */ @@ -144,17 +165,13 @@ ldbm_back_add( 0 ); next_id_return( be, e->e_id ); - /* XXX this should be ok, no other thread should have access - * because e hasn't been added to the cache yet - */ + entry_rdwr_unlock(e, 1);; entry_free( e ); + send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" ); return( -1 ); } - /* acquire writer lock */ - entry_rdwr_lock(e, 1); - /* * add it to the id2children index for the parent */ -- 2.39.5