-
Notifications
You must be signed in to change notification settings - Fork 960
use __asyncify in fd_read, allowing signal processing and DL operatio… #6485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Arshia001
wants to merge
7
commits into
main
Choose a base branch
from
fix/process-signals-during-fd-read
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
aaf001b
use __asyncify in fd_read, allowing signal processing and DL operatio…
Arshia001 98db504
Make clippy happy
Arshia001 02f13df
Add test, address review comments, fix implementation
Arshia001 a6cb4c3
WIP: address review comments
Arshia001 37aea2a
WIP: address review comments
Arshia001 a3513f5
Add test for EINTR-during-read
Arshia001 7334cdc
Merge branch 'main' into fix/process-signals-during-fd-read
Arshia001 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
lib/wasix/tests/wasm_tests/fd_tests/stdin-dlopen-race/build.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| export WASIXCC_PIC=yes | ||
|
|
||
| # Compile the shared library | ||
| $CC -shared side.c -o libside.so | ||
|
|
||
| # Compile the main executable | ||
| $CC main.c -o main | ||
|
Arshia001 marked this conversation as resolved.
|
||
71 changes: 71 additions & 0 deletions
71
lib/wasix/tests/wasm_tests/fd_tests/stdin-dlopen-race/main.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #include <dlfcn.h> | ||
| #include <pthread.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <unistd.h> | ||
|
|
||
| static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
| static int reader_ready = 0; | ||
|
|
||
| typedef int (*side_value_t)(void); | ||
|
|
||
| static void* reader_thread(void* arg) { | ||
| (void)arg; | ||
|
|
||
| /* Signal to the main thread that we are about to enter fd_read. */ | ||
| pthread_mutex_lock(&mutex); | ||
| reader_ready = 1; | ||
| pthread_cond_signal(&cond); | ||
| pthread_mutex_unlock(&mutex); | ||
|
|
||
| /* Block in fd_read on stdin. The host provides a pipe whose write end is | ||
| * never written to, so this call parks indefinitely. The process will be | ||
| * terminated by main() returning before this ever unblocks. */ | ||
| char buf[64]; | ||
| read(STDIN_FILENO, buf, sizeof(buf)); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| int main(void) { | ||
| pthread_t t; | ||
| pthread_create(&t, NULL, reader_thread, NULL); | ||
|
|
||
| /* Wait until the reader thread has set reader_ready (it is about to call | ||
| * read(), if it hasn't already). */ | ||
| pthread_mutex_lock(&mutex); | ||
| while (!reader_ready) pthread_cond_wait(&cond, &mutex); | ||
| pthread_mutex_unlock(&mutex); | ||
|
|
||
| printf("reader_ready\n"); | ||
|
|
||
| /* Give the reader thread time to actually enter the blocking read before | ||
| * attempting dlopen, so this test exercises the intended race reliably. */ | ||
| sleep(1); | ||
|
|
||
| /* Load a shared library while the other thread is blocked in fd_read. | ||
| * Before the fix this would deadlock because fd_read held a lock that | ||
| * the DL subsystem also needed. */ | ||
| void* handle = dlopen("libside.so", RTLD_NOW | RTLD_LOCAL); | ||
| if (!handle) { | ||
| fprintf(stderr, "dlopen failed: %s\n", dlerror()); | ||
| return 1; | ||
| } | ||
|
|
||
| printf("dlopen_succeeded_after_reader_ready\n"); | ||
|
|
||
| side_value_t side_value = (side_value_t)dlsym(handle, "side_value"); | ||
| if (!side_value) { | ||
| fprintf(stderr, "dlsym failed: %s\n", dlerror()); | ||
| dlclose(handle); | ||
| return 1; | ||
| } | ||
|
|
||
| printf("side_value=%d\n", side_value()); | ||
| printf("sequence_ok\n"); | ||
| dlclose(handle); | ||
|
|
||
| fflush(stdout); | ||
| _Exit(0); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| int side_value(void) { return 42; } |
4 changes: 4 additions & 0 deletions
4
lib/wasix/tests/wasm_tests/fd_tests/stdin-signal-eintr/build.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| $CC main.c -o main |
94 changes: 94 additions & 0 deletions
94
lib/wasix/tests/wasm_tests/fd_tests/stdin-signal-eintr/main.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| #include <errno.h> | ||
| #include <pthread.h> | ||
| #include <signal.h> | ||
| #include <stdio.h> | ||
| #include <string.h> | ||
| #include <unistd.h> | ||
|
|
||
| static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
| static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||
| static int reader_ready = 0; | ||
| static volatile sig_atomic_t handler_called = 0; | ||
| static int read_errno = 0; | ||
|
|
||
| static void signal_handler(int sig) { | ||
| (void)sig; | ||
| handler_called = 1; | ||
| } | ||
|
|
||
| static void* reader_thread(void* arg) { | ||
| (void)arg; | ||
|
|
||
| pthread_mutex_lock(&mutex); | ||
| reader_ready = 1; | ||
| pthread_cond_signal(&cond); | ||
| pthread_mutex_unlock(&mutex); | ||
|
|
||
| char buf[64]; | ||
| ssize_t ret = read(STDIN_FILENO, buf, sizeof(buf)); | ||
| if (ret >= 0) { | ||
| fprintf(stderr, "read unexpectedly succeeded: %zd\n", ret); | ||
| return (void*)1; | ||
| } | ||
|
|
||
| read_errno = errno; | ||
| return NULL; | ||
| } | ||
|
|
||
| int main(void) { | ||
| struct sigaction sa; | ||
| memset(&sa, 0, sizeof(sa)); | ||
| sa.sa_handler = signal_handler; | ||
| sigemptyset(&sa.sa_mask); | ||
| sa.sa_flags = 0; | ||
| if (sigaction(SIGUSR1, &sa, NULL) != 0) { | ||
| perror("sigaction"); | ||
| return 1; | ||
| } | ||
|
|
||
| pthread_t t; | ||
| if (pthread_create(&t, NULL, reader_thread, NULL) != 0) { | ||
| perror("pthread_create"); | ||
| return 1; | ||
| } | ||
|
|
||
| pthread_mutex_lock(&mutex); | ||
| while (!reader_ready) pthread_cond_wait(&cond, &mutex); | ||
| pthread_mutex_unlock(&mutex); | ||
|
|
||
| printf("reader_ready\n"); | ||
|
|
||
| // Give the reader thread time to actually enter the blocking read. | ||
| sleep(1); | ||
|
|
||
| if (pthread_kill(t, SIGUSR1) != 0) { | ||
| perror("pthread_kill"); | ||
| return 1; | ||
| } | ||
|
|
||
| printf("signal_sent\n"); | ||
|
|
||
| void* thread_ret = NULL; | ||
| if (pthread_join(t, &thread_ret) != 0) { | ||
| perror("pthread_join"); | ||
| return 1; | ||
| } | ||
| if (thread_ret != NULL) { | ||
| return 1; | ||
| } | ||
|
|
||
| if (!handler_called) { | ||
| fprintf(stderr, "signal handler was not called\n"); | ||
| return 1; | ||
| } | ||
| printf("handler_called\n"); | ||
|
|
||
| if (read_errno != EINTR) { | ||
| fprintf(stderr, "expected EINTR, got %d\n", read_errno); | ||
| return 1; | ||
| } | ||
|
|
||
| printf("read_errno=EINTR\n"); | ||
| printf("sequence_ok\n"); | ||
| return 0; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.