Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
HAMANO Tsukasa
OpenLDAP
Commits
272e4e98
Commit
272e4e98
authored
Apr 18, 2013
by
Howard Chu
Committed by
Hallvard Furuseth
Apr 18, 2013
Browse files
Add MDB_NOTLS envflag.
parent
afe488d8
Changes
2
Hide whitespace changes
Inline
Side-by-side
libraries/liblmdb/lmdb.h
View file @
272e4e98
...
...
@@ -66,6 +66,7 @@
*
* - A thread can only use one transaction at a time, plus any child
* transactions. Each transaction belongs to one thread. See below.
* The #MDB_NOTLS flag changes this for read-only transactions.
*
* - Use an MDB_env* in the process which opened it, without fork()ing.
*
...
...
@@ -249,6 +250,8 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
#define MDB_WRITEMAP 0x80000
/** use asynchronous msync when MDB_WRITEMAP is used */
#define MDB_MAPASYNC 0x100000
/** tie reader locktable slots to #MDB_txn objects instead of to threads */
#define MDB_NOTLS 0x200000
/** @} */
/** @defgroup mdb_dbi_open Database Flags
...
...
@@ -392,8 +395,8 @@ typedef struct MDB_envinfo {
size_t
me_mapsize
;
/**< Size of the data memory map */
size_t
me_last_pgno
;
/**< ID of the last used page */
size_t
me_last_txnid
;
/**< ID of the last committed transaction */
unsigned
int
me_maxreaders
;
/**< max
imum number of threads for
the environment */
unsigned
int
me_numreaders
;
/**< max
imum number of thread
s used in the environment */
unsigned
int
me_maxreaders
;
/**< max
reader slots in
the environment */
unsigned
int
me_numreaders
;
/**< max
reader slot
s used in the environment */
}
MDB_envinfo
;
/** @brief Return the mdb library version information.
...
...
@@ -492,6 +495,15 @@ int mdb_env_create(MDB_env **env);
* database or lose the last transactions. Calling #mdb_env_sync()
* ensures on-disk database integrity until next commit.
* This flag may be changed at any time using #mdb_env_set_flags().
* <li>#MDB_NOTLS
* Don't use Thread-Local Storage. Tie reader locktable slots to
* #MDB_txn objects instead of to threads. I.e. #mdb_txn_reset() keeps
* the slot reseved for the #MDB_txn object. A thread may use parallel
* read-only transactions. A read-only transaction may span threads if
* the user synchronizes its use. Applications that multiplex many
* user threads over individual OS threads need this option. Such an
* application must also serialize the write transactions in an OS
* thread, since MDB's write locking is unaware of the user threads.
* </ul>
* @param[in] mode The UNIX permissions to set on created files. This parameter
* is ignored on Windows.
...
...
@@ -626,13 +638,17 @@ int mdb_env_get_path(MDB_env *env, const char **path);
*/
int
mdb_env_set_mapsize
(
MDB_env
*
env
,
size_t
size
);
/** @brief Set the maximum number of threads for the environment.
/** @brief Set the maximum number of threads
/reader slots
for the environment.
*
* This defines the number of slots in the lock table that is used to track readers in the
* the environment. The default is 126.
* Starting a read-only transaction normally ties a lock table slot to the
* current thread until the environment closes or the thread exits. If
* MDB_NOTLS is in use, #mdb_txn_begin() instead ties the slot to the
* MDB_txn object until it or the #MDB_env object is destroyed.
* This function may only be called after #mdb_env_create() and before #mdb_env_open().
* @param[in] env An environment handle returned by #mdb_env_create()
* @param[in] readers The maximum number of
th
reads
* @param[in] readers The maximum number of read
er lock table slot
s
* @return A non-zero error value on failure and 0 on success. Some possible
* errors are:
* <ul>
...
...
@@ -641,7 +657,7 @@ int mdb_env_set_mapsize(MDB_env *env, size_t size);
*/
int
mdb_env_set_maxreaders
(
MDB_env
*
env
,
unsigned
int
readers
);
/** @brief Get the maximum number of threads for the environment.
/** @brief Get the maximum number of threads
/reader slots
for the environment.
*
* @param[in] env An environment handle returned by #mdb_env_create()
* @param[out] readers Address of an integer to store the number of readers
...
...
@@ -672,8 +688,9 @@ int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs);
/** @brief Create a transaction for use with the environment.
*
* The transaction handle may be discarded using #mdb_txn_abort() or #mdb_txn_commit().
* @note Transactions may not span threads; a transaction must only be used by a
* single thread. Also, a thread may only have a single transaction.
* @note A transaction and its cursors must only be used by a single
* thread, and a thread may only have a single transaction at a time.
* If #MDB_NOTLS is in use, this does not apply to read-only transactions.
* @note Cursors may not span transactions; each cursor must be opened and closed
* within a single transaction.
* @param[in] env An environment handle returned by #mdb_env_create()
...
...
@@ -730,11 +747,13 @@ void mdb_txn_abort(MDB_txn *txn);
/** @brief Reset a read-only transaction.
*
* This releases the current reader lock but doesn't free the
* transaction handle, allowing it to be used again later by #mdb_txn_renew().
* It otherwise has the same effect as #mdb_txn_abort() but saves some memory
* allocation/deallocation overhead if a thread is going to start a new
* read-only transaction again soon.
* Abort the transaction like #mdb_txn_abort(), but keep the transaction
* handle. #mdb_txn_renew() may reuse the handle. This saves allocation
* overhead if the process will start a new read-only transaction soon,
* and also locking overhead if #MDB_NOTLS is in use. The reader table
* lock is released, but the table slot stays tied to its thread or
* #MDB_txn. Use mdb_txn_abort() to discard a reset handle, and to free
* its lock table slot if MDB_NOTLS is in use.
* All cursors opened within the transaction must be closed before the transaction
* is reset.
* Reader locks generally don't interfere with writers, but they keep old
...
...
@@ -1045,8 +1064,8 @@ int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data);
/** @brief Create a cursor handle.
*
*
C
ursor
s are
associated with a specific transaction and database
and
*
may not span threa
ds.
*
A c
ursor
is
associated with a specific transaction and database
.
*
It must be closed before its transaction en
ds.
* @param[in] txn A transaction handle returned by #mdb_txn_begin()
* @param[in] dbi A database handle returned by #mdb_dbi_open()
* @param[out] cursor Address where the new #MDB_cursor handle will be stored
...
...
@@ -1067,8 +1086,9 @@ void mdb_cursor_close(MDB_cursor *cursor);
/** @brief Renew a cursor handle.
*
* Cursors are associated with a specific transaction and database and
* may not span threads. Cursors that are only used in read-only
* A cursor is associated with a specific transaction and database.
* It must be closed before its transaction ends.
* Cursors that are only used in read-only
* transactions may be re-used, to avoid unnecessary malloc/free overhead.
* The cursor may be associated with a new read-only transaction, and
* referencing the same database handle as it was created with.
...
...
libraries/liblmdb/mdb.c
View file @
272e4e98
...
...
@@ -406,6 +406,8 @@ typedef uint16_t indx_t;
* slot's address is saved in thread-specific data so that subsequent read
* transactions started by the same thread need no further locking to proceed.
*
* If #MDB_NOTLS is set, the slot address is not saved in thread-specific data.
*
* No reader table is used if the database is on a read-only filesystem.
*
* Since the database uses multi-version concurrency control, readers don't
...
...
@@ -1792,7 +1794,8 @@ mdb_txn_renew0(MDB_txn *txn)
txn
->
mt_txnid
=
env
->
me_metas
[
i
]
->
mm_txnid
;
txn
->
mt_u
.
reader
=
NULL
;
}
else
{
MDB_reader *r = pthread_getspecific(env->me_txkey);
MDB_reader
*
r
=
(
env
->
me_flags
&
MDB_NOTLS
)
?
txn
->
mt_u
.
reader
:
pthread_getspecific
(
env
->
me_txkey
);
if
(
r
)
{
if
(
r
->
mr_pid
!=
env
->
me_pid
||
r
->
mr_txnid
!=
(
txnid_t
)
-
1
)
return
MDB_BAD_RSLOT
;
...
...
@@ -1816,7 +1819,8 @@ mdb_txn_renew0(MDB_txn *txn)
env
->
me_numreaders
=
env
->
me_txns
->
mti_numreaders
;
UNLOCK_MUTEX_R
(
env
);
r
=
&
env
->
me_txns
->
mti_readers
[
i
];
if ((rc = pthread_setspecific(env->me_txkey, r)) != 0) {
if
(
!
(
env
->
me_flags
&
MDB_NOTLS
)
&&
(
rc
=
pthread_setspecific
(
env
->
me_txkey
,
r
))
!=
0
)
{
env
->
me_txns
->
mti_readers
[
i
].
mr_pid
=
0
;
return
rc
;
}
...
...
@@ -2006,7 +2010,8 @@ mdb_txn_reset0(MDB_txn *txn)
if
(
F_ISSET
(
txn
->
mt_flags
,
MDB_TXN_RDONLY
))
{
if
(
txn
->
mt_u
.
reader
)
{
txn
->
mt_u
.
reader
->
mr_txnid
=
(
txnid_t
)
-
1
;
txn->mt_u.reader = NULL; /* do not touch mr_txnid again */
if
(
!
(
env
->
me_flags
&
MDB_NOTLS
))
txn
->
mt_u
.
reader
=
NULL
;
/* txn does not own reader */
}
txn
->
mt_numdbs
=
0
;
/* mark txn as reset, do not close DBs again */
}
else
{
...
...
@@ -2091,6 +2096,10 @@ mdb_txn_abort(MDB_txn *txn)
mdb_txn_abort
(
txn
->
mt_child
);
mdb_txn_reset0
(
txn
);
/* Free reader slot tied to this txn (if MDB_NOTLS && writable FS) */
if
((
txn
->
mt_flags
&
MDB_TXN_RDONLY
)
&&
txn
->
mt_u
.
reader
)
txn
->
mt_u
.
reader
->
mr_pid
=
0
;
free
(
txn
);
}
...
...
@@ -3240,7 +3249,7 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl)
fcntl
(
env
->
me_lfd
,
F_SETFD
,
fdflags
);
#endif
{
if
(
!
(
env
->
me_flags
&
MDB_NOTLS
))
{
rc
=
pthread_key_create
(
&
env
->
me_txkey
,
mdb_env_reader_dest
);
if
(
rc
)
goto
fail
;
...
...
@@ -3418,7 +3427,7 @@ fail:
* environment and re-opening it with the new flags.
*/
#define CHANGEABLE (MDB_NOSYNC|MDB_NOMETASYNC|MDB_MAPASYNC)
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY|MDB_WRITEMAP)
#define CHANGELESS (MDB_FIXEDMAP|MDB_NOSUBDIR|MDB_RDONLY|MDB_WRITEMAP
|MDB_NOTLS
)
int
mdb_env_open
(
MDB_env
*
env
,
const
char
*
path
,
unsigned
int
flags
,
mdb_mode_t
mode
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment