From: Kurt Zeilenga Date: Fri, 22 Jan 1999 21:44:37 +0000 (+0000) Subject: Import entry_rwlock() call reordering to remove race condition. X-Git-Tag: OPENLDAP_REL_ENG_1_1_4~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1231b122634e83bd265ae20dfefdc5dcbea150d;p=thirdparty%2Fopenldap.git Import entry_rwlock() call reordering to remove race condition. --- diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 6faaf948f3..713372f24d 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -128,13 +128,35 @@ 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); + free( dn ); + + 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 */ @@ -149,18 +171,14 @@ 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 ); free( dn ); + 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 */