Cleanup for TLS key and read-only filesystem.

Move key init into mdb_env_setup_locks().
Don't create unused TLS key when read-only filesystem.
Drop internal flag MDB_ROFS, we can instead test either
!me_txns, !mt_u.reader or me_lfd==INVALID_HANDLE_VALUE.
vmware
Hallvard Furuseth 12 years ago
parent 65a6542765
commit ce6335b0d9
  1. 48
      libraries/liblmdb/mdb.c

@ -934,10 +934,10 @@ struct MDB_env {
HANDLE me_mfd; /**< just for writing the meta pages */ HANDLE me_mfd; /**< just for writing the meta pages */
/** Failed to update the meta page. Probably an I/O error. */ /** Failed to update the meta page. Probably an I/O error. */
#define MDB_FATAL_ERROR 0x80000000U #define MDB_FATAL_ERROR 0x80000000U
/** Read-only Filesystem. Allow read access, no locking. */
#define MDB_ROFS 0x40000000U
/** Some fields are initialized. */ /** Some fields are initialized. */
#define MDB_ENV_ACTIVE 0x20000000U #define MDB_ENV_ACTIVE 0x20000000U
/** me_txkey is set */
#define MDB_ENV_TXKEY 0x10000000U
uint32_t me_flags; /**< @ref mdb_env */ uint32_t me_flags; /**< @ref mdb_env */
unsigned int me_psize; /**< size of a page, from #GET_PAGESIZE */ unsigned int me_psize; /**< size of a page, from #GET_PAGESIZE */
unsigned int me_maxreaders; /**< size of the reader table */ unsigned int me_maxreaders; /**< size of the reader table */
@ -1786,7 +1786,7 @@ mdb_txn_renew0(MDB_txn *txn)
txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */ txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */
if (txn->mt_flags & MDB_TXN_RDONLY) { if (txn->mt_flags & MDB_TXN_RDONLY) {
if (env->me_flags & MDB_ROFS) { if (!env->me_txns) {
i = mdb_env_pick_meta(env); i = mdb_env_pick_meta(env);
txn->mt_txnid = env->me_metas[i]->mm_txnid; txn->mt_txnid = env->me_metas[i]->mm_txnid;
txn->mt_u.reader = NULL; txn->mt_u.reader = NULL;
@ -1999,8 +1999,9 @@ mdb_txn_reset0(MDB_txn *txn)
} }
if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) { if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
if (!(env->me_flags & MDB_ROFS)) if (txn->mt_u.reader) {
txn->mt_u.reader->mr_txnid = (txnid_t)-1; txn->mt_u.reader->mr_txnid = (txnid_t)-1;
}
} else { } else {
MDB_page *dp; MDB_page *dp;
@ -2771,7 +2772,7 @@ mdb_env_create(MDB_env **env)
return ENOMEM; return ENOMEM;
e->me_maxreaders = DEFAULT_READERS; e->me_maxreaders = DEFAULT_READERS;
e->me_maxdbs = 2; e->me_maxdbs = e->me_numdbs = 2;
e->me_fd = INVALID_HANDLE_VALUE; e->me_fd = INVALID_HANDLE_VALUE;
e->me_lfd = INVALID_HANDLE_VALUE; e->me_lfd = INVALID_HANDLE_VALUE;
e->me_mfd = INVALID_HANDLE_VALUE; e->me_mfd = INVALID_HANDLE_VALUE;
@ -3218,7 +3219,6 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
if (env->me_lfd == INVALID_HANDLE_VALUE) { if (env->me_lfd == INVALID_HANDLE_VALUE) {
rc = ErrCode(); rc = ErrCode();
if (rc == MDB_ERRCODE_ROFS && (env->me_flags & MDB_RDONLY)) { if (rc == MDB_ERRCODE_ROFS && (env->me_flags & MDB_RDONLY)) {
env->me_flags |= MDB_ROFS;
return MDB_SUCCESS; return MDB_SUCCESS;
} }
goto fail_errno; goto fail_errno;
@ -3229,6 +3229,21 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
fcntl(env->me_lfd, F_SETFD, fdflags); fcntl(env->me_lfd, F_SETFD, fdflags);
#endif #endif
{
rc = pthread_key_create(&env->me_txkey, mdb_env_reader_dest);
if (rc)
goto fail;
env->me_flags |= MDB_ENV_TXKEY;
#ifdef _WIN32
/* Windows TLS callbacks need help finding their TLS info. */
if (mdb_tls_nkeys >= MAX_TLS_KEYS) {
rc = MDB_TLS_FULL;
goto fail;
}
mdb_tls_keys[mdb_tls_nkeys++] = env->me_txkey;
#endif
}
/* Try to get exclusive lock. If we succeed, then /* Try to get exclusive lock. If we succeed, then
* nobody is using the lock region and we should initialize it. * nobody is using the lock region and we should initialize it.
*/ */
@ -3492,19 +3507,6 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
} }
} }
DPRINTF("opened dbenv %p", (void *) env); DPRINTF("opened dbenv %p", (void *) env);
rc = pthread_key_create(&env->me_txkey, mdb_env_reader_dest);
if (rc)
goto leave;
env->me_numdbs = 2; /* this notes that me_txkey was set */
#ifdef _WIN32
/* Windows TLS callbacks need help finding their TLS info. */
if (mdb_tls_nkeys < MAX_TLS_KEYS)
mdb_tls_keys[mdb_tls_nkeys++] = env->me_txkey;
else {
rc = MDB_TLS_FULL;
goto leave;
}
#endif
if (excl > 0) { if (excl > 0) {
rc = mdb_env_share_locks(env, &excl); rc = mdb_env_share_locks(env, &excl);
} }
@ -3534,7 +3536,7 @@ mdb_env_close0(MDB_env *env, int excl)
if (env->me_free_pgs) if (env->me_free_pgs)
mdb_midl_free(env->me_free_pgs); mdb_midl_free(env->me_free_pgs);
if (env->me_numdbs) { if (env->me_flags & MDB_ENV_TXKEY) {
pthread_key_delete(env->me_txkey); pthread_key_delete(env->me_txkey);
#ifdef _WIN32 #ifdef _WIN32
/* Delete our key from the global list */ /* Delete our key from the global list */
@ -3600,7 +3602,7 @@ mdb_env_close0(MDB_env *env, int excl)
close(env->me_lfd); close(env->me_lfd);
} }
env->me_flags &= ~MDB_ENV_ACTIVE; env->me_flags &= ~(MDB_ENV_ACTIVE|MDB_ENV_TXKEY);
} }
int int
@ -3659,7 +3661,7 @@ mdb_env_copy(MDB_env *env, const char *path)
if (rc) if (rc)
goto leave; goto leave;
if (!(env->me_flags & MDB_ROFS)) { if (env->me_txns) {
/* We must start the actual read txn after blocking writers */ /* We must start the actual read txn after blocking writers */
mdb_txn_reset0(txn); mdb_txn_reset0(txn);
@ -3684,7 +3686,7 @@ mdb_env_copy(MDB_env *env, const char *path)
rc = write(newfd, env->me_map, wsize); rc = write(newfd, env->me_map, wsize);
rc = (rc == (int)wsize) ? MDB_SUCCESS : ErrCode(); rc = (rc == (int)wsize) ? MDB_SUCCESS : ErrCode();
#endif #endif
if (! (env->me_flags & MDB_ROFS)) if (env->me_txns)
UNLOCK_MUTEX_W(env); UNLOCK_MUTEX_W(env);
if (rc) if (rc)

Loading…
Cancel
Save