|
|
@ -1185,7 +1185,8 @@ struct MDB_env { |
|
|
|
unsigned int me_psize; /**< DB page size, inited from me_os_psize */ |
|
|
|
unsigned int me_psize; /**< DB page size, inited from me_os_psize */ |
|
|
|
unsigned int me_os_psize; /**< OS page size, from #GET_PAGESIZE */ |
|
|
|
unsigned int me_os_psize; /**< OS page size, from #GET_PAGESIZE */ |
|
|
|
unsigned int me_maxreaders; /**< size of the reader table */ |
|
|
|
unsigned int me_maxreaders; /**< size of the reader table */ |
|
|
|
unsigned int me_numreaders; /**< max numreaders set by this env */ |
|
|
|
/** Max #MDB_txninfo.%mti_numreaders of interest to #mdb_env_close() */ |
|
|
|
|
|
|
|
volatile int me_close_readers; |
|
|
|
MDB_dbi me_numdbs; /**< number of DBs opened */ |
|
|
|
MDB_dbi me_numdbs; /**< number of DBs opened */ |
|
|
|
MDB_dbi me_maxdbs; /**< size of the DB table */ |
|
|
|
MDB_dbi me_maxdbs; /**< size of the DB table */ |
|
|
|
MDB_PID_T me_pid; /**< process ID of this env */ |
|
|
|
MDB_PID_T me_pid; /**< process ID of this env */ |
|
|
@ -2603,13 +2604,19 @@ mdb_txn_renew0(MDB_txn *txn) |
|
|
|
return MDB_READERS_FULL; |
|
|
|
return MDB_READERS_FULL; |
|
|
|
} |
|
|
|
} |
|
|
|
r = &ti->mti_readers[i]; |
|
|
|
r = &ti->mti_readers[i]; |
|
|
|
|
|
|
|
/* Claim the reader slot, carefully since other code
|
|
|
|
|
|
|
|
* uses the reader table un-mutexed: First reset the |
|
|
|
|
|
|
|
* slot, next publish it in mti_numreaders. After |
|
|
|
|
|
|
|
* that, it is safe for mdb_env_close() to touch it. |
|
|
|
|
|
|
|
* When it will be closed, we can finally claim it. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
r->mr_pid = 0; |
|
|
|
r->mr_txnid = (txnid_t)-1; |
|
|
|
r->mr_txnid = (txnid_t)-1; |
|
|
|
r->mr_tid = tid; |
|
|
|
r->mr_tid = tid; |
|
|
|
r->mr_pid = pid; /* should be written last, see ITS#7971. */ |
|
|
|
|
|
|
|
if (i == nr) |
|
|
|
if (i == nr) |
|
|
|
ti->mti_numreaders = ++nr; |
|
|
|
ti->mti_numreaders = ++nr; |
|
|
|
/* Save numreaders for un-mutexed mdb_env_close() */ |
|
|
|
env->me_close_readers = nr; |
|
|
|
env->me_numreaders = nr; |
|
|
|
r->mr_pid = pid; |
|
|
|
UNLOCK_MUTEX(rmutex); |
|
|
|
UNLOCK_MUTEX(rmutex); |
|
|
|
|
|
|
|
|
|
|
|
new_notls = (env->me_flags & MDB_NOTLS); |
|
|
|
new_notls = (env->me_flags & MDB_NOTLS); |
|
|
@ -4790,8 +4797,12 @@ mdb_env_close0(MDB_env *env, int excl) |
|
|
|
MDB_PID_T pid = env->me_pid; |
|
|
|
MDB_PID_T pid = env->me_pid; |
|
|
|
/* Clearing readers is done in this function because
|
|
|
|
/* Clearing readers is done in this function because
|
|
|
|
* me_txkey with its destructor must be disabled first. |
|
|
|
* me_txkey with its destructor must be disabled first. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* We skip the the reader mutex, so we touch only |
|
|
|
|
|
|
|
* data owned by this process (me_close_readers and |
|
|
|
|
|
|
|
* our readers), and clear each reader atomically. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
for (i = env->me_numreaders; --i >= 0; ) |
|
|
|
for (i = env->me_close_readers; --i >= 0; ) |
|
|
|
if (env->me_txns->mti_readers[i].mr_pid == pid) |
|
|
|
if (env->me_txns->mti_readers[i].mr_pid == pid) |
|
|
|
env->me_txns->mti_readers[i].mr_pid = 0; |
|
|
|
env->me_txns->mti_readers[i].mr_pid = 0; |
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
@ -9110,11 +9121,7 @@ mdb_env_info(MDB_env *env, MDB_envinfo *arg) |
|
|
|
arg->me_mapaddr = env->me_metas[toggle]->mm_address; |
|
|
|
arg->me_mapaddr = env->me_metas[toggle]->mm_address; |
|
|
|
arg->me_mapsize = env->me_mapsize; |
|
|
|
arg->me_mapsize = env->me_mapsize; |
|
|
|
arg->me_maxreaders = env->me_maxreaders; |
|
|
|
arg->me_maxreaders = env->me_maxreaders; |
|
|
|
|
|
|
|
arg->me_numreaders = env->me_txns ? env->me_txns->mti_numreaders : 0; |
|
|
|
/* me_numreaders may be zero if this process never used any readers. Use
|
|
|
|
|
|
|
|
* the shared numreader count if it exists. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
arg->me_numreaders = env->me_txns ? env->me_txns->mti_numreaders : env->me_numreaders; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
arg->me_last_pgno = env->me_metas[toggle]->mm_last_pg; |
|
|
|
arg->me_last_pgno = env->me_metas[toggle]->mm_last_pg; |
|
|
|
arg->me_last_txnid = env->me_metas[toggle]->mm_txnid; |
|
|
|
arg->me_last_txnid = env->me_metas[toggle]->mm_txnid; |
|
|
|