case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
if( txn != NULL ) {
boi->boi_err = rc;
}
- return LDAP_OTHER;
+ return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
}
if (e == NULL) {
#ifdef NEW_LOGGING
#define bv2DBT(bv,t) ((t)->data = (bv)->bv_val, \
(t)->size = (bv)->bv_len )
-#define BDB_TXN_RETRIES 16
+#define BDB_TXN_RETRIES 16
+
+#define BDB_MAX_ADD_LOOP 30
#ifdef BDB_SUBDIRS
#define BDB_TMP_SUBDIR LDAP_DIRSEP "tmp"
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
send_ldap_result( conn, op, rc=LDAP_OTHER,
NULL, "internal error", NULL, NULL );
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
ch_free( data.data );
}
- if (rc == 0 && bdb_cache_add_entry_rw(&bdb->bi_cache, *e, rw) != 0) {
- if ((*e)->e_private != NULL)
+ while (rc == 0 && bdb_cache_add_entry_rw(&bdb->bi_cache, *e, rw) != 0) {
+ Entry *ee;
+ int add_loop_cnt = 0;
+ if ( (*e)->e_private != NULL ) {
free ((*e)->e_private);
+ }
(*e)->e_private = NULL;
- bdb_entry_return (*e);
- if ((*e=bdb_cache_find_entry_id(&bdb->bi_cache,id,rw)) != NULL) {
+ if ( (ee = bdb_cache_find_entry_id
+ (&bdb->bi_cache, id, rw) ) != NULL) {
+ bdb_entry_return ( *e );
+ *e = ee;
return 0;
}
+ if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
+ bdb_entry_return ( *e );
+ *e = NULL;
+ return LDAP_BUSY;
+ }
}
#ifdef BDB_HIER
goto retry;
case DB_NOTFOUND:
break;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
}
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
+ case LDAP_BUSY:
+ text = "ldap server busy";
+ goto return_results;
default:
rc = LDAP_OTHER;
text = "internal error";
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ *text = "ldap server busy";
+ goto done;
default:
rc = LDAP_OTHER;
*text = "internal error";
rc = 0;
case 0:
break;
+ case LDAP_BUSY:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, e);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, matched);
+ }
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
#ifdef NEW_LOGGING
LDAP_LOG (( "referral", LDAP_LEVEL_ERR,
case DB_NOTFOUND:
case 0:
break;
+ case LDAP_BUSY:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, e);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(&bdb->bi_cache, matched);
+ }
+ send_ldap_result( conn, op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ return LDAP_BUSY;
default:
if (e != NULL) {
bdb_cache_return_entry_r(&bdb->bi_cache, e);
/* get the entry with reader lock */
rc = bdb_id2entry_r( be, NULL, id, &e );
+ if (rc == LDAP_BUSY) {
+ send_ldap_result( conn, op, rc=LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ goto done;
+ }
+
if ( e == NULL ) {
if( !BDB_IDL_IS_RANGE(candidates) ) {
/* only complain for non-range IDLs */