From 77e8e46bdfbc132fb083a1888fb192aee42accf2 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 29 Jan 2002 17:49:37 +0000 Subject: [PATCH] Back out giant lock code, needs more work --- servers/slapd/back-ldbm/add.c | 53 ++++++++++++++++++++--------- servers/slapd/back-ldbm/back-ldbm.h | 4 ++- servers/slapd/back-ldbm/bind.c | 7 +--- servers/slapd/back-ldbm/compare.c | 6 ---- servers/slapd/back-ldbm/delete.c | 16 +++++---- servers/slapd/back-ldbm/entry.c | 2 +- servers/slapd/back-ldbm/init.c | 8 +++-- servers/slapd/back-ldbm/modify.c | 5 --- servers/slapd/back-ldbm/modrdn.c | 14 ++++---- servers/slapd/back-ldbm/nextid.c | 8 +++++ servers/slapd/back-ldbm/passwd.c | 7 +--- servers/slapd/back-ldbm/referral.c | 7 ---- servers/slapd/back-ldbm/search.c | 7 ---- 13 files changed, 74 insertions(+), 70 deletions(-) diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 9baac81065..997e969f1d 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -27,6 +27,7 @@ ldbm_back_add( struct ldbminfo *li = (struct ldbminfo *) be->be_private; struct berval pdn; Entry *p = NULL; + int rootlock = 0; int rc; ID id = NOID; const char *text = NULL; @@ -41,12 +42,12 @@ ldbm_back_add( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0); #endif - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); + /* nobody else can add until we lock our parent */ + ldap_pvt_thread_mutex_lock(&li->li_add_mutex); if ( ( rc = dn2id( be, &e->e_nname, &id ) ) || id != NOID ) { /* if (rc) something bad happened to ldbm cache */ - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); send_ldap_result( conn, op, rc ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS, NULL, NULL, NULL, NULL ); @@ -56,7 +57,7 @@ ldbm_back_add( rc = entry_schema_check( be, e, NULL, &text, textbuf, textlen ); if ( rc != LDAP_SUCCESS ) { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -67,6 +68,7 @@ ldbm_back_add( text, 0, 0 ); #endif + send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); return( -1 ); @@ -92,6 +94,8 @@ ldbm_back_add( char *matched_dn = NULL; BerVarray refs; + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + if ( matched != NULL ) { matched_dn = ch_strdup( matched->e_dn ); refs = is_entry_referral( matched ) @@ -104,8 +108,6 @@ ldbm_back_add( NULL, &e->e_name, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, "ldbm_back_add: Parent of (%s) does not exist.\n", @@ -125,12 +127,14 @@ ldbm_back_add( return -1; } + /* don't need the add lock anymore */ + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + if ( ! access_allowed( be, conn, op, p, children, NULL, ACL_WRITE ) ) { /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -144,6 +148,7 @@ ldbm_back_add( send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, "no write access to parent", NULL, NULL ); + return -1; } @@ -152,7 +157,6 @@ ldbm_back_add( /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -178,7 +182,6 @@ ldbm_back_add( /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -211,7 +214,7 @@ ldbm_back_add( p = NULL; if ( ! rc ) { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -233,7 +236,7 @@ ldbm_back_add( } } else { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -253,6 +256,14 @@ ldbm_back_add( return -1; } } + + /* + * no parent, acquire the root write lock + * and release the add lock. + */ + ldap_pvt_thread_mutex_lock(&li->li_root_mutex); + rootlock = 1; + ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); } if ( next_id( be, &e->e_id ) ) { @@ -261,16 +272,20 @@ ldbm_back_add( cache_return_entry_w( &li->li_cache, p ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + if ( rootlock ) { + /* release root lock */ + ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); + } #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, - "ldbm_back_add: next_id failed.\n" )); + "ldbm_back_add: next_id failed.\n" )); #else Debug( LDAP_DEBUG_ANY, "ldbm_add: next_id failed\n", 0, 0, 0 ); #endif + send_ldap_result( conn, op, LDAP_OTHER, NULL, "next_id add failed", NULL, NULL ); @@ -288,7 +303,10 @@ ldbm_back_add( cache_return_entry_w( &li->li_cache, p ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + if ( rootlock ) { + /* release root lock */ + ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); + } #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_ERR, @@ -374,13 +392,16 @@ return_results:; cache_return_entry_w( &li->li_cache, p ); } + if ( rootlock ) { + /* release root lock */ + ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); + } + if ( rc ) { /* in case of error, writer lock is freed * and entry's private data is destroyed */ cache_return_entry_w( &li->li_cache, e ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - return( rc ); } diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h index c74d84c408..a1072adc74 100644 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ b/servers/slapd/back-ldbm/back-ldbm.h @@ -125,8 +125,10 @@ typedef struct ldbm_dbcache { #define MAXDBCACHE 128 struct ldbminfo { - ldap_pvt_thread_rdwr_t li_giant_rwlock; ID li_nextid; + ldap_pvt_thread_mutex_t li_nextid_mutex; + ldap_pvt_thread_mutex_t li_root_mutex; + ldap_pvt_thread_mutex_t li_add_mutex; int li_mode; slap_mask_t li_defaultmask; char *li_directory; diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c index ddadbad7b1..a6ab1c5e29 100644 --- a/servers/slapd/back-ldbm/bind.c +++ b/servers/slapd/back-ldbm/bind.c @@ -50,10 +50,8 @@ ldbm_back_bind( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn->bv_val, 0, 0); #endif - dn = ndn; - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); + dn = ndn; /* get entry with reader lock */ if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) { @@ -74,8 +72,6 @@ ldbm_back_bind( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - /* allow noauth binds */ rc = 1; if ( method == LDAP_AUTH_SIMPLE ) { @@ -267,7 +263,6 @@ ldbm_back_bind( return_results:; /* free entry and reader lock */ cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); /* front end with send result on success (rc==0) */ return( rc ); diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c index b5ca4f6618..b3494b4964 100644 --- a/servers/slapd/back-ldbm/compare.c +++ b/servers/slapd/back-ldbm/compare.c @@ -33,9 +33,6 @@ ldbm_back_compare( int rc; int manageDSAit = get_manageDSAit( op ); - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - /* get entry with reader lock */ if ( (e = dn2entry_r( be, ndn, &matched )) == NULL ) { char *matched_dn = NULL; @@ -52,8 +49,6 @@ ldbm_back_compare( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -120,6 +115,5 @@ ldbm_back_compare( return_results:; cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); return( rc ); } diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index 874fe4f156..a3b5ebe902 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -29,6 +29,7 @@ ldbm_back_delete( Entry *matched; struct berval pdn; Entry *e, *p = NULL; + int rootlock = 0; int rc = -1; int manageDSAit = get_manageDSAit( op ); AttributeDescription *children = slap_schema.si_ad_children; @@ -40,9 +41,6 @@ ldbm_back_delete( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn->bv_val, 0, 0); #endif - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - /* get entry with writer lock */ if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) { char *matched_dn = NULL; @@ -68,8 +66,6 @@ ldbm_back_delete( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -200,6 +196,9 @@ ldbm_back_delete( goto return_results; } } + + ldap_pvt_thread_mutex_lock(&li->li_root_mutex); + rootlock = 1; } /* delete from dn2id mapping */ @@ -249,10 +248,13 @@ return_results:; cache_return_entry_w( &li->li_cache, p ); } + if ( rootlock ) { + /* release root lock */ + ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); + } + /* free entry and writer lock */ cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - return rc; } diff --git a/servers/slapd/back-ldbm/entry.c b/servers/slapd/back-ldbm/entry.c index f018d2b129..28267e39fb 100644 --- a/servers/slapd/back-ldbm/entry.c +++ b/servers/slapd/back-ldbm/entry.c @@ -31,8 +31,8 @@ ldbm_back_entry_release_rw( if ( slapMode == SLAP_SERVER_MODE ) { /* free entry and reader or writer lock */ cache_return_entry_rw( &li->li_cache, e, rw ); - } else { + entry_free( e ); } diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c index 1c1af991f8..1fe1335666 100644 --- a/servers/slapd/back-ldbm/init.c +++ b/servers/slapd/back-ldbm/init.c @@ -172,8 +172,10 @@ ldbm_back_db_init( li->li_dbshutdown = 0; /* initialize various mutex locks & condition variables */ - ldap_pvt_thread_rdwr_init( &li->li_giant_rwlock ); + ldap_pvt_thread_mutex_init( &li->li_root_mutex ); + ldap_pvt_thread_mutex_init( &li->li_add_mutex ); ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex ); + ldap_pvt_thread_mutex_init( &li->li_nextid_mutex ); ldap_pvt_thread_mutex_init( &li->li_dbcache_mutex ); ldap_pvt_thread_cond_init( &li->li_dbcache_cv ); @@ -223,8 +225,10 @@ ldbm_back_db_destroy( free( li->li_directory ); attr_index_destroy( li->li_attrs ); - ldap_pvt_thread_rdwr_destroy( &li->li_giant_rwlock ); + ldap_pvt_thread_mutex_destroy( &li->li_root_mutex ); + ldap_pvt_thread_mutex_destroy( &li->li_add_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_cache.c_mutex ); + ldap_pvt_thread_mutex_destroy( &li->li_nextid_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_dbcache_mutex ); ldap_pvt_thread_cond_destroy( &li->li_dbcache_cv ); diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 6948d2ffd8..c7978238a2 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -297,8 +297,6 @@ ldbm_back_modify( Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0); #endif - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); /* acquire and lock entry */ if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) { @@ -316,7 +314,6 @@ ldbm_back_modify( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -373,11 +370,9 @@ ldbm_back_modify( NULL, NULL, NULL, NULL ); cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); return( 0 ); error_return:; cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); return( -1 ); } diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index f2e2dfb6d6..195fa4d434 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -88,9 +88,6 @@ ldbm_back_modrdn( ? newSuperior->bv_val : "NULL", 0 ); #endif - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - /* get entry with writer lock */ if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) { char* matched_dn = NULL; @@ -107,8 +104,6 @@ ldbm_back_modrdn( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -267,6 +262,9 @@ ldbm_back_modrdn( } } + ldap_pvt_thread_mutex_lock(&li->li_root_mutex); + rootlock = 1; + #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_INFO, "ldbm_back_modrdn: (%s) no parent, locked root.\n", e->e_dn )); @@ -806,6 +804,11 @@ return_results: cache_return_entry_w( &li->li_cache, p ); } + if ( rootlock ) { + /* release root writer lock */ + ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); + } + /* free entry and writer lock */ cache_return_entry_w( &li->li_cache, e ); if ( rc == MUST_DESTROY ) { @@ -814,6 +817,5 @@ return_results: * the entry must be freed */ entry_free( e ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); return( rc ); } diff --git a/servers/slapd/back-ldbm/nextid.c b/servers/slapd/back-ldbm/nextid.c index 80f6f0f61f..2bdcde3871 100644 --- a/servers/slapd/back-ldbm/nextid.c +++ b/servers/slapd/back-ldbm/nextid.c @@ -102,8 +102,11 @@ next_id_get( Backend *be, ID *idp ) *idp = NOID; + ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex ); + if ( li->li_nextid == NOID ) { if ( ( rc = next_id_read( be, idp ) ) ) { + ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex ); return( rc ); } li->li_nextid = *idp; @@ -111,6 +114,7 @@ next_id_get( Backend *be, ID *idp ) *idp = li->li_nextid; + ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex ); return( rc ); } @@ -120,8 +124,11 @@ next_id( Backend *be, ID *idp ) struct ldbminfo *li = (struct ldbminfo *) be->be_private; int rc = 0; + ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex ); + if ( li->li_nextid == NOID ) { if ( ( rc = next_id_read( be, idp ) ) ) { + ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex ); return( rc ); } li->li_nextid = *idp; @@ -132,5 +139,6 @@ next_id( Backend *be, ID *idp ) rc = -1; } + ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex ); return( rc ); } diff --git a/servers/slapd/back-ldbm/passwd.c b/servers/slapd/back-ldbm/passwd.c index 8ad0948f09..1f04c48555 100644 --- a/servers/slapd/back-ldbm/passwd.c +++ b/servers/slapd/back-ldbm/passwd.c @@ -31,7 +31,7 @@ ldbm_back_exop_passwd( ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; - int rc, locked=0; + int rc; Entry *e = NULL; struct berval hash = { 0, NULL }; @@ -108,12 +108,8 @@ ldbm_back_exop_passwd( goto done; } - /* grab giant lock for writing */ - ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); - e = dn2entry_w( be, &ndn, NULL ); if( e == NULL ) { - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); *text = "could not locate authorization entry"; rc = LDAP_NO_SUCH_OBJECT; goto done; @@ -177,7 +173,6 @@ ldbm_back_exop_passwd( done: if( e != NULL ) { cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); } if( hash.bv_val != NULL ) { diff --git a/servers/slapd/back-ldbm/referral.c b/servers/slapd/back-ldbm/referral.c index 48bb7886cc..05d51e0919 100644 --- a/servers/slapd/back-ldbm/referral.c +++ b/servers/slapd/back-ldbm/referral.c @@ -38,9 +38,6 @@ ldbm_back_referrals( return rc; } - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); - /* get entry with reader lock */ e = dn2entry_r( be, ndn, &matched ); if ( e == NULL ) { @@ -73,8 +70,6 @@ ldbm_back_referrals( NULL, dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - if( refs != NULL ) { /* send referrals */ send_ldap_result( conn, op, rc = LDAP_REFERRAL, @@ -122,7 +117,5 @@ ldbm_back_referrals( } cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - return rc; } diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index c61b921ac6..c80359f8c6 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -64,8 +64,6 @@ ldbm_back_search( Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0); #endif - /* grab giant lock for reading */ - ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); if ( nbase->bv_len == 0 ) { /* DIT root special case */ @@ -118,8 +116,6 @@ ldbm_back_search( NULL, base, scope ); } - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - send_ldap_result( conn, op, err, matched_dn.bv_val, text, refs, NULL ); @@ -139,7 +135,6 @@ ldbm_back_search( refs = NULL; cache_return_entry_r( &li->li_cache, e ); - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); #ifdef NEW_LOGGING LDAP_LOG(( "backend", LDAP_LEVEL_INFO, @@ -511,8 +506,6 @@ loop_continue: rc = 0; done: - ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); - if( candidates != NULL ) idl_free( candidates ); -- 2.39.5