From 363b36492c2672c410470f76287428ba86fc30f5 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 29 Jan 2002 20:29:38 +0000 Subject: [PATCH] Import LDBM giant lock code from HEAD. --- CHANGES | 2 ++ servers/slapd/back-ldbm/add.c | 49 +++++++++-------------------- servers/slapd/back-ldbm/back-ldbm.h | 4 +-- servers/slapd/back-ldbm/bind.c | 6 ++++ servers/slapd/back-ldbm/cache.c | 14 +++++++++ servers/slapd/back-ldbm/compare.c | 6 ++++ servers/slapd/back-ldbm/delete.c | 16 +++++----- servers/slapd/back-ldbm/entry.c | 6 ++++ servers/slapd/back-ldbm/init.c | 8 ++--- servers/slapd/back-ldbm/modify.c | 6 ++++ servers/slapd/back-ldbm/modrdn.c | 14 ++++----- servers/slapd/back-ldbm/nextid.c | 8 ----- servers/slapd/back-ldbm/passwd.c | 8 +++-- servers/slapd/back-ldbm/referral.c | 7 +++++ servers/slapd/back-ldbm/search.c | 8 +++++ 15 files changed, 91 insertions(+), 71 deletions(-) diff --git a/CHANGES b/CHANGES index 5ae3ff6bff..02c48dcce8 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ OpenLDAP 2.0 Change Log OpenLDAP 2.0.22 Engineering Fixed slapd passwd modify referral bug + Fixed back-ldbm index threading bug Fixed back-ldbm ordering presense index bug Fixed back-ldap modify bug (ITS#1547) Fixed -lldap TLS errno bug @@ -154,6 +155,7 @@ OpenLDAP 2.0.12 Release Updated ldaptcl API (contrib) Updated -lldap SASL/TLS referral handling Updated -lldap pthread code + Updated ldapmodify add/replace handling Removed -lldap UFN search support Build environment Removed extraneous files diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 7a399ce1d1..d5908de764 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -27,7 +27,6 @@ ldbm_back_add( struct ldbminfo *li = (struct ldbminfo *) be->be_private; char *pdn; Entry *p = NULL; - int rootlock = 0; int rc; ID id = NOID; const char *text = NULL; @@ -37,13 +36,12 @@ ldbm_back_add( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0); - - /* nobody else can add until we lock our parent */ - ldap_pvt_thread_mutex_lock(&li->li_add_mutex); + /* grab giant lock for writing */ + ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); if ( ( rc = dn2id( be, e->e_ndn, &id ) ) || id != NOID ) { /* if (rc) something bad happened to ldbm cache */ - ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); send_ldap_result( conn, op, rc ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS, NULL, NULL, NULL, NULL ); @@ -53,7 +51,7 @@ ldbm_back_add( rc = entry_schema_check( e, NULL, &text, textbuf, textlen ); if ( rc != LDAP_SUCCESS ) { - ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n", text, 0, 0 ); @@ -82,8 +80,6 @@ ldbm_back_add( char *matched_dn; struct berval **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 ) @@ -96,6 +92,8 @@ ldbm_back_add( refs = default_referral; } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0, 0, 0 ); @@ -113,9 +111,6 @@ ldbm_back_add( return -1; } - /* don't need the add lock anymore */ - ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); - free(pdn); if ( ! access_allowed( be, conn, op, p, @@ -123,6 +118,7 @@ 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); Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", 0, 0, 0 ); @@ -130,7 +126,6 @@ ldbm_back_add( send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, "no write access to parent", NULL, NULL ); - return -1; } @@ -139,6 +134,7 @@ 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); Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0, 0, 0 ); @@ -159,6 +155,7 @@ 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); Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0, 0, 0 ); @@ -189,7 +186,7 @@ ldbm_back_add( p = NULL; if ( ! rc ) { - ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", @@ -204,7 +201,7 @@ ldbm_back_add( return -1; } } else { - ldap_pvt_thread_mutex_unlock(&li->li_add_mutex); + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_TRACE, "%s add denied\n", pdn == NULL ? "suffix" @@ -217,14 +214,6 @@ 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 ) ) { @@ -233,10 +222,7 @@ ldbm_back_add( cache_return_entry_w( &li->li_cache, p ); } - if ( rootlock ) { - /* release root lock */ - ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); - } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_ANY, "ldbm_add: next_id failed\n", 0, 0, 0 ); @@ -259,10 +245,7 @@ ldbm_back_add( cache_return_entry_w( &li->li_cache, p ); } - if ( rootlock ) { - /* release root lock */ - ldap_pvt_thread_mutex_unlock(&li->li_root_mutex); - } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0, 0 ); @@ -329,15 +312,11 @@ 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 44ec01e170..73b67acf8f 100644 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ b/servers/slapd/back-ldbm/back-ldbm.h @@ -103,10 +103,8 @@ 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 2e8404e6c1..ece3a57f05 100644 --- a/servers/slapd/back-ldbm/bind.c +++ b/servers/slapd/back-ldbm/bind.c @@ -48,6 +48,9 @@ ldbm_back_bind( *edn = NULL; dn = ndn; + /* grab giant lock for reading */ + ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); + /* get entry with reader lock */ if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) { char *matched_dn = NULL; @@ -65,6 +68,8 @@ ldbm_back_bind( refs = default_referral; } + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + /* allow noauth binds */ rc = 1; if ( method == LDAP_AUTH_SIMPLE ) { @@ -246,6 +251,7 @@ 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/cache.c b/servers/slapd/back-ldbm/cache.c index 7d2e1fc97d..caddcb5f97 100644 --- a/servers/slapd/back-ldbm/cache.c +++ b/servers/slapd/back-ldbm/cache.c @@ -19,7 +19,9 @@ /* LDBM backend specific entry info -- visible only to the cache */ typedef struct ldbm_entry_info { +#ifdef LDBM_ENTRY_RWLOCK ldap_pvt_thread_rdwr_t lei_rdwr; /* reader/writer lock */ +#endif /* * remaining fields require backend cache lock to access @@ -45,6 +47,7 @@ static int cache_delete_entry_internal(Cache *cache, Entry *e); static void lru_print(Cache *cache); #endif +#ifdef LDBM_ENTRY_RWLOCK static int cache_entry_rdwr_lock(Entry *e, int rw) { @@ -92,6 +95,7 @@ cache_entry_rdwr_destroy(Entry *e) { return ldap_pvt_thread_rdwr_destroy( &LEI(e)->lei_rdwr ); } +#endif static int cache_entry_private_init( Entry*e ) @@ -105,11 +109,13 @@ cache_entry_private_init( Entry*e ) e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info)); +#ifdef LDBM_ENTRY_RWLOCK if( cache_entry_rdwr_init( e ) != 0 ) { free( LEI(e) ); e->e_private = NULL; return 1; } +#endif return 0; } @@ -136,7 +142,9 @@ cache_entry_private_destroy( Entry*e ) { assert( e->e_private ); +#ifdef LDBM_ENTRY_RWLOCK cache_entry_rdwr_destroy( e ); +#endif free( e->e_private ); e->e_private = NULL; @@ -154,7 +162,9 @@ cache_return_entry_rw( Cache *cache, Entry *e, int rw ) assert( e->e_private ); +#ifdef LDBM_ENTRY_RWLOCK cache_entry_rdwr_unlock(e, rw); +#endif id = e->e_id; refcnt = --LEI(e)->lei_refcnt; @@ -309,7 +319,9 @@ cache_add_entry_rw( return( -1 ); } +#ifdef LDBM_ENTRY_RWLOCK cache_entry_rdwr_lock( e, rw ); +#endif /* put the entry into 'CREATING' state */ /* will be marked after when entry is returned */ @@ -610,6 +622,7 @@ try_again: goto try_again; } +#ifdef LDBM_ENTRY_RWLOCK /* acquire reader lock */ if ( cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) { /* could not acquire entry lock... @@ -627,6 +640,7 @@ try_again: ldap_pvt_thread_yield(); goto try_again; } +#endif /* lru */ LRU_DELETE( cache, ep ); diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c index 85a48c6926..bd6fc609ba 100644 --- a/servers/slapd/back-ldbm/compare.c +++ b/servers/slapd/back-ldbm/compare.c @@ -33,6 +33,9 @@ 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; @@ -48,6 +51,8 @@ ldbm_back_compare( refs = default_referral; } + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -111,5 +116,6 @@ 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 3a80ed6c2a..3c54c90a28 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -29,13 +29,15 @@ ldbm_back_delete( Entry *matched; char *pdn = NULL; Entry *e, *p = NULL; - int rootlock = 0; int rc = -1; int manageDSAit = get_manageDSAit( op ); AttributeDescription *children = slap_schema.si_ad_children; Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn, 0, 0); + /* 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; @@ -54,6 +56,8 @@ ldbm_back_delete( refs = default_referral; } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -150,9 +154,6 @@ ldbm_back_delete( goto return_results; } } - - ldap_pvt_thread_mutex_lock(&li->li_root_mutex); - rootlock = 1; } /* delete from dn2id mapping */ @@ -190,13 +191,10 @@ 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 32d98a528d..39e33602b1 100644 --- a/servers/slapd/back-ldbm/entry.c +++ b/servers/slapd/back-ldbm/entry.c @@ -29,5 +29,11 @@ ldbm_back_entry_release_rw( /* free entry and reader or writer lock */ cache_return_entry_rw( &li->li_cache, e, rw ); + if(rw) { + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + } else { + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + } + return 0; } diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c index f9a7ccd458..542a84995a 100644 --- a/servers/slapd/back-ldbm/init.c +++ b/servers/slapd/back-ldbm/init.c @@ -171,10 +171,8 @@ ldbm_back_db_init( li->li_dbshutdown = 0; /* initialize various mutex locks & condition variables */ - ldap_pvt_thread_mutex_init( &li->li_root_mutex ); - ldap_pvt_thread_mutex_init( &li->li_add_mutex ); + ldap_pvt_thread_rdwr_init( &li->li_giant_rwlock ); 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 ); @@ -224,10 +222,8 @@ ldbm_back_db_destroy( free( li->li_directory ); attr_index_destroy( li->li_attrs ); - ldap_pvt_thread_mutex_destroy( &li->li_root_mutex ); - ldap_pvt_thread_mutex_destroy( &li->li_add_mutex ); + ldap_pvt_thread_rdwr_destroy( &li->li_giant_rwlock ); 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 c8d046931c..84cf3d5f41 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -189,6 +189,9 @@ ldbm_back_modify( Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0); + /* 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 ) { char* matched_dn = NULL; @@ -204,6 +207,7 @@ ldbm_back_modify( refs = default_referral; } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -256,10 +260,12 @@ 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 d529cda34f..eacc4d9ca8 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -80,6 +80,9 @@ ldbm_back_modrdn( (newSuperior ? newSuperior : "NULL"), 0, 0 ); + /* 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; @@ -95,6 +98,8 @@ ldbm_back_modrdn( refs = default_referral; } + ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + send_ldap_result( conn, op, LDAP_REFERRAL, matched_dn, NULL, refs, NULL ); @@ -204,9 +209,6 @@ ldbm_back_modrdn( } } - ldap_pvt_thread_mutex_lock(&li->li_root_mutex); - rootlock = 1; - Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: no parent, locked root\n", 0, 0, 0 ); @@ -631,11 +633,6 @@ 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 ) { @@ -644,5 +641,6 @@ 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 9995425577..39b388ab0c 100644 --- a/servers/slapd/back-ldbm/nextid.c +++ b/servers/slapd/back-ldbm/nextid.c @@ -95,11 +95,8 @@ 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; @@ -107,7 +104,6 @@ next_id_get( Backend *be, ID *idp ) *idp = li->li_nextid; - ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex ); return( rc ); } @@ -117,11 +113,8 @@ 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,6 +125,5 @@ 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 92f87136b5..f15badec31 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; + int rc, locked=0; Entry *e = NULL; struct berval *hash = NULL; @@ -90,9 +90,12 @@ ldbm_back_exop_passwd( goto done; } - e = dn2entry_w( be, dn, NULL ); + /* grab giant lock for writing */ + ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); + e = dn2entry_w( be, dn, 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; @@ -154,6 +157,7 @@ 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( id != NULL ) { diff --git a/servers/slapd/back-ldbm/referral.c b/servers/slapd/back-ldbm/referral.c index 13b71a5c90..a0451f21ee 100644 --- a/servers/slapd/back-ldbm/referral.c +++ b/servers/slapd/back-ldbm/referral.c @@ -38,6 +38,9 @@ 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 ) { @@ -58,6 +61,8 @@ ldbm_back_referrals( cache_return_entry_r( &li->li_cache, matched ); } + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + if( refs != NULL ) { /* send referrals */ send_ldap_result( conn, op, rc = LDAP_REFERRAL, @@ -90,5 +95,7 @@ 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 f234c2faa3..9a7a0a16f2 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -55,6 +55,9 @@ ldbm_back_search( Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0); + /* grab giant lock for reading */ + ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock); + if ( *nbase == '\0' ) { /* DIT root special case */ static const Entry root = { NOID, "", "", NULL, NULL }; @@ -98,6 +101,8 @@ ldbm_back_search( refs = default_referral; } + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + send_ldap_result( conn, op, err, matched_dn, text, refs, NULL ); @@ -116,6 +121,7 @@ ldbm_back_search( conn, op, e ); cache_return_entry_r( &li->li_cache, e ); + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); Debug( LDAP_DEBUG_TRACE, "ldbm_search: entry is referral\n", @@ -349,6 +355,8 @@ loop_continue: rc = 0; done: + ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); + if( candidates != NULL ) idl_free( candidates ); -- 2.39.5