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;
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 );
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,
text, 0, 0 );
#endif
+
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
return( -1 );
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 )
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",
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,
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, "no write access to parent", NULL, NULL );
+
return -1;
}
/* 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,
/* 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,
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,
}
} 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,
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 ) ) {
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 );
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,
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 );
}
#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;
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 ) {
NULL, dn, LDAP_SCOPE_DEFAULT );
}
- ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
-
/* allow noauth binds */
rc = 1;
if ( method == LDAP_AUTH_SIMPLE ) {
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 );
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;
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 );
return_results:;
cache_return_entry_r( &li->li_cache, e );
- ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
return( rc );
}
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;
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;
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 );
goto return_results;
}
}
+
+ ldap_pvt_thread_mutex_lock(&li->li_root_mutex);
+ rootlock = 1;
}
/* delete from dn2id mapping */
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;
}
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 );
}
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 );
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 );
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 ) {
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 );
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 );
}
? 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;
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 );
}
}
+ 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 ));
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 ) {
* the entry must be freed */
entry_free( e );
}
- ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
return( rc );
}
*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;
*idp = li->li_nextid;
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
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;
rc = -1;
}
+ ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- int rc, locked=0;
+ int rc;
Entry *e = NULL;
struct berval hash = { 0, NULL };
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;
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 ) {
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 ) {
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,
}
cache_return_entry_r( &li->li_cache, e );
- ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
-
return rc;
}
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 */
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 );
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,
rc = 0;
done:
- ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
-
if( candidates != NULL )
idl_free( candidates );