mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
Windows thread callback support
This commit is contained in:
parent
e562f53e10
commit
248fd1c7b8
@ -2568,11 +2568,8 @@ mdb_env_open2(MDB_env *env, unsigned int flags)
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
/** Release a reader thread's slot in the reader lock table.
|
||||
* This function is called automatically when a thread exits.
|
||||
* Windows doesn't support destructor callbacks for thread-specific storage,
|
||||
* so this function is not compiled there.
|
||||
* @param[in] ptr This points to the slot in the reader lock table.
|
||||
*/
|
||||
static void
|
||||
@ -2584,6 +2581,60 @@ mdb_env_reader_dest(void *ptr)
|
||||
reader->mr_pid = 0;
|
||||
reader->mr_tid = 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/** Junk for arranging thread-specific callbacks on Windows. This is
|
||||
* necessarily platform and compiler-specific. Windows supports up
|
||||
* to 1088 keys. Let's assume nobody opens more than 64 environments
|
||||
* in a single process, for now. They can override this if needed.
|
||||
*/
|
||||
#ifndef MAX_TLS_KEYS
|
||||
#define MAX_TLS_KEYS 64
|
||||
#endif
|
||||
static pthread_key_t mdb_tls_keys[MAX_TLS_KEYS];
|
||||
static int mdb_tls_nkeys;
|
||||
|
||||
static void NTAPI mdb_tls_callback(PVOID module, DWORD reason, PVOID ptr)
|
||||
{
|
||||
int i;
|
||||
switch(reason) {
|
||||
case DLL_PROCESS_ATTACH: break;
|
||||
case DLL_THREAD_ATTACH: break;
|
||||
case DLL_THREAD_DETACH:
|
||||
for (i=0; i<mdb_tls_nkeys; i++) {
|
||||
MDB_reader *r = pthread_getspecific(mdb_tls_keys[i]);
|
||||
mdb_env_reader_dest(r);
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH: break;
|
||||
}
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
#ifdef _WIN64
|
||||
const PIMAGE_TLS_CALLBACK mdb_tls_cbp __attribute__((section (".CRT$XLB"))) = mdb_tls_callback;
|
||||
#else
|
||||
PIMAGE_TLS_CALLBACK mdb_tls_cbp __attribute__((section (".CRT$XLB"))) = mdb_tls_callback;
|
||||
#endif
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
/* Force some symbol references.
|
||||
* _tls_used forces the linker to create the TLS directory if not already done
|
||||
* mdb_tls_cbp prevents whole-program-optimizer from dropping the symbol.
|
||||
*/
|
||||
#pragma comment(linker, "/INCLUDE:_tls_used")
|
||||
#pragma comment(linker, "/INCLUDE:mdb_tls_cbp")
|
||||
#pragma const_seg(".CRT$XLB")
|
||||
extern const PIMAGE_TLS_CALLBACK mdb_tls_callback;
|
||||
const PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
|
||||
#pragma const_seg()
|
||||
#else /* WIN32 */
|
||||
#pragma comment(linker, "/INCLUDE:__tls_used")
|
||||
#pragma comment(linker, "/INCLUDE:_mdb_tls_cbp")
|
||||
#pragma data_seg(".CRT$XLB")
|
||||
PIMAGE_TLS_CALLBACK mdb_tls_cbp = mdb_tls_callback;
|
||||
#pragma data_seg()
|
||||
#endif /* WIN 32/64 */
|
||||
#endif /* !__GNUC__ */
|
||||
#endif
|
||||
|
||||
/** Downgrade the exclusive lock on the region back to shared */
|
||||
@ -3040,6 +3091,15 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mode_t mode)
|
||||
env->me_path = strdup(path);
|
||||
DPRINTF("opened dbenv %p", (void *) env);
|
||||
pthread_key_create(&env->me_txkey, mdb_env_reader_dest);
|
||||
#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 = ENOMEM;
|
||||
goto leave;
|
||||
}
|
||||
#endif
|
||||
LAZY_RWLOCK_INIT(&env->me_dblock, NULL);
|
||||
if (excl)
|
||||
mdb_env_share_locks(env);
|
||||
@ -3087,6 +3147,17 @@ mdb_env_close(MDB_env *env)
|
||||
|
||||
LAZY_RWLOCK_DESTROY(&env->me_dblock);
|
||||
pthread_key_delete(env->me_txkey);
|
||||
#ifdef _WIN32
|
||||
/* Delete our key from the global list */
|
||||
{ int i;
|
||||
for (i=0; i<mdb_tls_nkeys; i++)
|
||||
if (mdb_tls_keys[i] == env->me_txkey) {
|
||||
mdb_tls_keys[i] = mdb_tls_keys[mdb_tls_nkeys-1];
|
||||
mdb_tls_nkeys--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (env->me_map) {
|
||||
munmap(env->me_map, env->me_mapsize);
|
||||
|
Loading…
Reference in New Issue
Block a user