Remove extra lock-taking in preopen setup (#491)

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
This commit is contained in:
Andrew Brown 2024-05-02 14:07:27 -07:00 committed by GitHub
parent 129ee9b64b
commit 887613873d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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();