mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:04:13 +08:00
mdbx: avoid 32-bit Bionic/Android hang within pthread_mutex_lock()
.
This commit is contained in:
parent
51d66494fd
commit
a2aa6667e1
@ -1248,7 +1248,7 @@ static __inline void rthc_lock(void) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
EnterCriticalSection(&rthc_critical_section);
|
EnterCriticalSection(&rthc_critical_section);
|
||||||
#else
|
#else
|
||||||
mdbx_ensure(nullptr, pthread_mutex_lock(&rthc_mutex) == 0);
|
mdbx_ensure(nullptr, mdbx_pthread_mutex_lock(&rthc_mutex) == 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,7 +1596,7 @@ static __inline void lcklist_lock(void) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
EnterCriticalSection(&lcklist_critical_section);
|
EnterCriticalSection(&lcklist_critical_section);
|
||||||
#else
|
#else
|
||||||
mdbx_ensure(nullptr, pthread_mutex_lock(&lcklist_mutex) == 0);
|
mdbx_ensure(nullptr, mdbx_pthread_mutex_lock(&lcklist_mutex) == 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,11 +812,32 @@ __cold static int mdbx_ipclock_failed(MDBX_env *env, mdbx_ipclock_t *ipc,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__ANDROID_API__) || defined(ANDROID) || defined(BIONIC)
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_check_tid4bionic(void) {
|
||||||
|
/* avoid 32-bit Bionic bug/hang with 32-pit TID */
|
||||||
|
if (sizeof(pthread_mutex_t) < sizeof(pid_t) + sizeof(unsigned)) {
|
||||||
|
pid_t tid = gettid();
|
||||||
|
if (unlikely(tid > 0xffff)) {
|
||||||
|
mdbx_fatal("Raise the ENOSYS(%d) error to avoid hang due "
|
||||||
|
"the 32-bit Bionic/Android bug with tid/thread_id 0x%08x(%i) "
|
||||||
|
"that don’t fit in 16 bits, see "
|
||||||
|
"https://android.googlesource.com/platform/bionic/+/master/"
|
||||||
|
"docs/32-bit-abi.md#is-too-small-for-large-pids",
|
||||||
|
ENOSYS, tid, tid);
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* __ANDROID_API__ || ANDROID) || BIONIC */
|
||||||
|
|
||||||
static int mdbx_ipclock_lock(MDBX_env *env, mdbx_ipclock_t *ipc,
|
static int mdbx_ipclock_lock(MDBX_env *env, mdbx_ipclock_t *ipc,
|
||||||
const bool dont_wait) {
|
const bool dont_wait) {
|
||||||
#if MDBX_LOCKING == MDBX_LOCKING_POSIX2001 || \
|
#if MDBX_LOCKING == MDBX_LOCKING_POSIX2001 || \
|
||||||
MDBX_LOCKING == MDBX_LOCKING_POSIX2008
|
MDBX_LOCKING == MDBX_LOCKING_POSIX2008
|
||||||
int rc = dont_wait ? pthread_mutex_trylock(ipc) : pthread_mutex_lock(ipc);
|
int rc = mdbx_check_tid4bionic();
|
||||||
|
if (likely(rc == 0))
|
||||||
|
rc = dont_wait ? pthread_mutex_trylock(ipc) : pthread_mutex_lock(ipc);
|
||||||
rc = (rc == EBUSY && dont_wait) ? MDBX_BUSY : rc;
|
rc = (rc == EBUSY && dont_wait) ? MDBX_BUSY : rc;
|
||||||
#elif MDBX_LOCKING == MDBX_LOCKING_POSIX1988
|
#elif MDBX_LOCKING == MDBX_LOCKING_POSIX1988
|
||||||
int rc = MDBX_SUCCESS;
|
int rc = MDBX_SUCCESS;
|
||||||
|
@ -437,7 +437,7 @@ MDBX_INTERNAL_FUNC int mdbx_condpair_lock(mdbx_condpair_t *condpair) {
|
|||||||
DWORD code = WaitForSingleObject(condpair->mutex, INFINITE);
|
DWORD code = WaitForSingleObject(condpair->mutex, INFINITE);
|
||||||
return waitstatus2errcode(code);
|
return waitstatus2errcode(code);
|
||||||
#else
|
#else
|
||||||
return pthread_mutex_lock(&condpair->mutex);
|
return mdbx_pthread_mutex_lock(&condpair->mutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +507,7 @@ MDBX_INTERNAL_FUNC int mdbx_fastmutex_acquire(mdbx_fastmutex_t *fastmutex) {
|
|||||||
}
|
}
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
#else
|
#else
|
||||||
return pthread_mutex_lock(fastmutex);
|
return mdbx_pthread_mutex_lock(fastmutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
src/osal.h
15
src/osal.h
@ -730,6 +730,7 @@ MDBX_MAYBE_UNUSED static __inline uint32_t mdbx_getpid(void) {
|
|||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
return GetCurrentProcessId();
|
return GetCurrentProcessId();
|
||||||
#else
|
#else
|
||||||
|
STATIC_ASSERT(sizeof(pid_t) <= sizeof(uint32_t));
|
||||||
return getpid();
|
return getpid();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -745,6 +746,20 @@ MDBX_MAYBE_UNUSED static __inline uintptr_t mdbx_thread_self(void) {
|
|||||||
return (uintptr_t)thunk;
|
return (uintptr_t)thunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
|
#if defined(__ANDROID_API__) || defined(ANDROID) || defined(BIONIC)
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_check_tid4bionic(void);
|
||||||
|
#else
|
||||||
|
static __inline int mdbx_check_tid4bionic(void) { return 0; }
|
||||||
|
#endif /* __ANDROID_API__ || ANDROID) || BIONIC */
|
||||||
|
|
||||||
|
MDBX_MAYBE_UNUSED static __inline int
|
||||||
|
mdbx_pthread_mutex_lock(pthread_mutex_t *mutex) {
|
||||||
|
int err = mdbx_check_tid4bionic();
|
||||||
|
return unlikely(err) ? err : pthread_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
#endif /* !Windows */
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC uint64_t mdbx_osal_monotime(void);
|
MDBX_INTERNAL_FUNC uint64_t mdbx_osal_monotime(void);
|
||||||
MDBX_INTERNAL_FUNC uint64_t
|
MDBX_INTERNAL_FUNC uint64_t
|
||||||
mdbx_osal_16dot16_to_monotime(uint32_t seconds_16dot16);
|
mdbx_osal_16dot16_to_monotime(uint32_t seconds_16dot16);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user