void bdb_locker_id_free( void *key, void *data ) { DB_ENV *env = key; int lockid = (int) data; XLOCK_ID_FREE( env, lockid ); }
int bdb_locker_id( Operation *op, DB_ENV *env, int *locker ) { int i, rc, lockid; void *data; void *ctx; if ( !env || !locker ) return -1; /* If no op was provided, try to find the ctx anyway... */ if ( op ) { ctx = op->o_threadctx; } else { ctx = ldap_pvt_thread_pool_context( &connection_pool ); } /* Shouldn't happen unless we're single-threaded */ if ( !ctx ) { *locker = 0; return 0; } if ( ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) { for ( i=0, rc=1; rc != 0 && i<4; i++ ) { rc = XLOCK_ID( env, &lockid ); if (rc) ldap_pvt_thread_yield(); } if ( rc != 0) { return rc; } data = (void *)lockid; if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env, data, bdb_locker_id_free ) ) ) { XLOCK_ID_FREE( env, lockid ); #ifdef NEW_LOGGING LDAP_LOG( BACK_BDB, ERR, "bdb_locker_id: err %s(%d)\n", db_strerror(rc), rc, 0 ); #else Debug( LDAP_DEBUG_ANY, "bdb_locker_id: err %s(%d)\n", db_strerror(rc), rc, 0 ); #endif return rc; } } else { lockid = (int)data; } *locker = lockid; return 0; }
static int bdb_db_close( BackendDB *be, ConfigReply *cr ) { int rc; struct bdb_info *bdb = (struct bdb_info *) be->be_private; struct bdb_db_info *db; bdb_idl_cache_entry_t *entry, *next_entry; /* monitor handling */ (void)bdb_monitor_db_close( be ); { Entry *e = bdb->bi_cache.c_dntree.bei_e; if ( e ) { bdb->bi_cache.c_dntree.bei_e = NULL; e->e_private = NULL; bdb_entry_return( e ); } } bdb->bi_flags &= ~BDB_IS_OPEN; ber_bvarray_free( bdb->bi_db_config ); bdb->bi_db_config = NULL; while( bdb->bi_databases && bdb->bi_ndatabases-- ) { db = bdb->bi_databases[bdb->bi_ndatabases]; rc = db->bdi_db->close( db->bdi_db, 0 ); /* Lower numbered names are not strdup'd */ if( bdb->bi_ndatabases >= BDB_NDB ) free( db->bdi_name.bv_val ); free( db ); } free( bdb->bi_databases ); bdb->bi_databases = NULL; bdb_cache_release_all (&bdb->bi_cache); if ( bdb->bi_idl_cache_size ) { avl_free( bdb->bi_idl_tree, NULL ); bdb->bi_idl_tree = NULL; entry = bdb->bi_idl_lru_head; do { next_entry = entry->idl_lru_next; if ( entry->idl ) free( entry->idl ); free( entry->kstr.bv_val ); free( entry ); entry = next_entry; } while ( entry != bdb->bi_idl_lru_head ); bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL; } /* close db environment */ if( bdb->bi_dbenv ) { /* Free cache locker if we enabled locking */ if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_cache.c_locker ) { #if DB_VERSION_FULL >= 0x04060012 XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker->id); #else XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker); #endif bdb->bi_cache.c_locker = 0; } #ifdef BDB_REUSE_LOCKERS bdb_locker_flush( bdb->bi_dbenv ); #endif /* force a checkpoint, but not if we were ReadOnly, * and not in Quick mode since there are no transactions there. */ if ( !( slapMode & ( SLAP_TOOL_QUICK|SLAP_TOOL_READONLY ))) { rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "bdb_db_close: database \"%s\": " "txn_checkpoint failed: %s (%d).\n", be->be_suffix[0].bv_val, db_strerror(rc), rc ); } } rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 ); bdb->bi_dbenv = NULL; if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "bdb_db_close: database \"%s\": " "close failed: %s (%d)\n", be->be_suffix[0].bv_val, db_strerror(rc), rc ); return rc; } } rc = alock_close( &bdb->bi_alock_info, slapMode & SLAP_TOOL_QUICK ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "bdb_db_close: database \"%s\": alock_close failed\n", be->be_suffix[0].bv_val, 0, 0 ); return -1; } return 0; }