From 055295943756cf3cc8238dba741777b1e45fe948 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 30 Jul 2018 15:58:23 +0300 Subject: pthread: Implement implicit sem init This should be undefined behaviour, but some android apps rely on default initialized semaphores. (Hearthstone) --- src/libpthread.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/libpthread.c b/src/libpthread.c index 515b7df..f001c47 100644 --- a/src/libpthread.c +++ b/src/libpthread.c @@ -132,6 +132,15 @@ bionic_sem_destroy(bionic_sem_t *sem) return ret; } +static void +default_sem_init(bionic_sem_t *sem) +{ + // Apparently some android apps (hearthstone) do not call sem_init() + assert(sem); + sem->glibc = mmap(NULL, sizeof(*sem->glibc), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); + memset(sem->glibc, 0, sizeof(*sem->glibc)); +} + int bionic_sem_init(bionic_sem_t *sem, int pshared, unsigned int value) { @@ -146,28 +155,32 @@ bionic_sem_init(bionic_sem_t *sem, int pshared, unsigned int value) int bionic_sem_post(bionic_sem_t *sem) { - assert(sem && IS_MAPPED(sem)); + assert(sem); + INIT_IF_NOT_MAPPED(sem, default_sem_init); return sem_post(sem->glibc); } int bionic_sem_wait(bionic_sem_t *sem) { - assert(sem && IS_MAPPED(sem)); + assert(sem); + INIT_IF_NOT_MAPPED(sem, default_sem_init); return sem_wait(sem->glibc); } int bionic_sem_trywait(bionic_sem_t *sem) { - assert(sem && IS_MAPPED(sem)); + assert(sem); + INIT_IF_NOT_MAPPED(sem, default_sem_init); return sem_trywait(sem->glibc); } int bionic_sem_timedwait(bionic_sem_t *sem, const struct timespec *abs_timeout) { - assert(sem && IS_MAPPED(sem) && abs_timeout); + assert(sem && abs_timeout); + INIT_IF_NOT_MAPPED(sem, default_sem_init); return sem_timedwait(sem->glibc, abs_timeout); } -- cgit v1.2.3