Add GIANT rwlock! This should resolve nasty concurrency issues.

This commit is contained in:
Kurt Zeilenga 2002-01-29 17:27:20 +00:00
parent 3a10cc1e43
commit 634cca7f0d
13 changed files with 70 additions and 74 deletions

View file

@ -27,7 +27,6 @@ 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;
@ -42,12 +41,12 @@ ldbm_back_add(
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
#endif
/* 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_nname, &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 );
@ -57,7 +56,7 @@ ldbm_back_add(
rc = entry_schema_check( be, 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);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -68,7 +67,6 @@ ldbm_back_add(
text, 0, 0 );
#endif
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
return( -1 );
@ -94,8 +92,6 @@ 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 )
@ -108,6 +104,8 @@ 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",
@ -127,14 +125,12 @@ 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,
@ -148,7 +144,6 @@ ldbm_back_add(
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, "no write access to parent", NULL, NULL );
return -1;
}
@ -157,6 +152,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);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -182,6 +178,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);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -214,7 +211,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);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -236,7 +233,7 @@ ldbm_back_add(
}
} else {
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -256,14 +253,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 ) ) {
@ -272,20 +261,16 @@ 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);
#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 );
@ -303,10 +288,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);
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
@ -392,16 +374,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);
}
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 );
}

View file

@ -125,10 +125,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;

View file

@ -50,9 +50,11 @@ 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);
/* get entry with reader lock */
if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
char *matched_dn = NULL;
@ -72,6 +74,8 @@ 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 ) {
@ -263,6 +267,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 );

View file

@ -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;
@ -49,6 +52,8 @@ 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 );
@ -115,5 +120,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 );
}

View file

@ -29,7 +29,6 @@ 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;
@ -41,6 +40,9 @@ 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;
@ -66,6 +68,8 @@ 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 );
@ -196,9 +200,6 @@ ldbm_back_delete(
goto return_results;
}
}
ldap_pvt_thread_mutex_lock(&li->li_root_mutex);
rootlock = 1;
}
/* delete from dn2id mapping */
@ -248,13 +249,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;
}

View file

@ -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 );
}

View file

@ -172,10 +172,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 );
@ -225,10 +223,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 );

View file

@ -297,6 +297,8 @@ 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 ) {
@ -314,6 +316,7 @@ 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 );
@ -370,9 +373,11 @@ 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 );
}

View file

@ -88,6 +88,9 @@ 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;
@ -104,6 +107,8 @@ 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 );
@ -262,9 +267,6 @@ 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 ));
@ -804,11 +806,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 ) {
@ -817,5 +814,6 @@ return_results:
* the entry must be freed */
entry_free( e );
}
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
return( rc );
}

View file

@ -102,11 +102,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;
@ -114,7 +111,6 @@ next_id_get( Backend *be, ID *idp )
*idp = li->li_nextid;
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
@ -124,11 +120,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;
@ -139,6 +132,5 @@ next_id( Backend *be, ID *idp )
rc = -1;
}
ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}

View file

@ -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 = { 0, NULL };
@ -108,8 +108,12 @@ 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;
@ -173,6 +177,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( hash.bv_val != NULL ) {

View file

@ -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 ) {
@ -70,6 +73,8 @@ 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,
@ -117,5 +122,7 @@ ldbm_back_referrals(
}
cache_return_entry_r( &li->li_cache, e );
ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
return rc;
}

View file

@ -64,6 +64,8 @@ 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 */
@ -116,6 +118,8 @@ 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 );
@ -135,6 +139,7 @@ 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,
@ -506,6 +511,8 @@ loop_continue:
rc = 0;
done:
ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
if( candidates != NULL )
idl_free( candidates );