From e8745ea5bbe1a6bd7e50949a632240960dcbc77f Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 26 Apr 2024 16:10:45 -0700 Subject: [PATCH] Remove extra lock-taking in preopen setup Issue [#8392] in Wasmtime highlights how preopen registration can result in a hang when compiled for a threaded environment. The problem is that `internal_register_preopened_fd_unlocked` assumes it will not touch the global lock because its caller, `__wasilibc_populate_preopens`, already has taken the lock. Unfortunately, a refactoring in #408 (which introduces `internal_register_preopened_fd_unlocked`) did not catch that the `resize` function called internally also takes the global lock. This change removes that locking in `resize` under the assumption that it will only be called when the lock is already taken. [#8392]: https://github.com/bytecodealliance/wasmtime/issues/8392 --- libc-bottom-half/sources/preopens.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libc-bottom-half/sources/preopens.c b/libc-bottom-half/sources/preopens.c index 3386ca4e..21ac8cc6 100644 --- a/libc-bottom-half/sources/preopens.c +++ b/libc-bottom-half/sources/preopens.c @@ -59,7 +59,6 @@ static void assert_invariants(void) { /// Allocate space for more preopens. Returns 0 on success and -1 on failure. static int resize(void) { - LOCK(lock); size_t start_capacity = 4; size_t old_capacity = preopen_capacity; size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2; @@ -67,7 +66,6 @@ static int resize(void) { preopen *old_preopens = preopens; preopen *new_preopens = calloc(sizeof(preopen), new_capacity); if (new_preopens == NULL) { - UNLOCK(lock); return -1; } @@ -77,7 +75,6 @@ static int resize(void) { free(old_preopens); assert_invariants(); - UNLOCK(lock); return 0; } @@ -101,8 +98,7 @@ static const char *strip_prefixes(const char *path) { return path; } -/// Similar to `internal_register_preopened_fd_unlocked` but does not -/// take a lock. +/// Similar to `internal_register_preopened_fd` but does not take a lock. static int internal_register_preopened_fd_unlocked(__wasi_fd_t fd, const char *relprefix) { // Check preconditions. assert_invariants();