mdbx: avoid 32-bit Bionic/Android hang within pthread_mutex_lock().

This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2022-04-21 15:41:25 +03:00
parent 51d66494fd
commit a2aa6667e1
4 changed files with 41 additions and 5 deletions

View File

@@ -812,11 +812,32 @@ __cold static int mdbx_ipclock_failed(MDBX_env *env, mdbx_ipclock_t *ipc,
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 dont 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,
const bool dont_wait) {
#if MDBX_LOCKING == MDBX_LOCKING_POSIX2001 || \
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;
#elif MDBX_LOCKING == MDBX_LOCKING_POSIX1988
int rc = MDBX_SUCCESS;