-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Fix pending signals to be TLS #26666
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
Merged
Merged
Changes from all commits
Commits
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
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
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
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
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
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
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
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,133 @@ | ||
| /** | ||
| * Copyright 2026 The Emscripten Authors. All rights reserved. | ||
| * Emscripten is available under two separate licenses, the MIT license and the | ||
| * University of Illinois/NCSA Open Source License. Both these licenses can be | ||
| * found in the LICENSE file. | ||
| */ | ||
|
|
||
| #include <pthread.h> | ||
| #include <sys/types.h> | ||
| #include <stdbool.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <assert.h> | ||
| #include <unistd.h> | ||
| #include <errno.h> | ||
| #include <signal.h> | ||
|
|
||
| pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; | ||
| pthread_cond_t started = PTHREAD_COND_INITIALIZER; | ||
| pthread_cond_t unblock = PTHREAD_COND_INITIALIZER; | ||
| pthread_cond_t pending = PTHREAD_COND_INITIALIZER; | ||
| _Atomic bool got_sigterm = false; | ||
| _Atomic bool is_pending = false; | ||
| _Atomic bool unblock_signal = false; | ||
|
|
||
| pthread_t child_thread; | ||
|
|
||
| void signal_handler(int sig, siginfo_t * info, void * arg) { | ||
| printf("signal_handler: sig=%d onthread=%d\n", sig, pthread_self() == child_thread); | ||
| assert(sig == SIGTERM); | ||
| assert(pthread_self() == child_thread); | ||
| got_sigterm = true; | ||
| } | ||
|
|
||
| void setup_handler() { | ||
| struct sigaction act; | ||
| sigemptyset(&act.sa_mask); | ||
| act.sa_flags = SA_SIGINFO; | ||
| act.sa_sigaction = signal_handler; | ||
| sigaction(SIGTERM, &act, NULL); | ||
| } | ||
|
|
||
| void sleepms(long msecs) { | ||
| usleep(msecs * 1000); | ||
| } | ||
|
|
||
| void *thread_start(void *arg) { | ||
| sigset_t set; | ||
| int ret; | ||
|
|
||
| // First we block all signals. | ||
| sigfillset(&set); | ||
| pthread_sigmask(SIG_BLOCK, &set, NULL); | ||
|
|
||
| // Now we signal that we are running | ||
| pthread_mutex_lock(&lock); | ||
| pthread_cond_signal(&started); | ||
| pthread_mutex_unlock(&lock); | ||
|
|
||
| printf("Waiting for SIGTERM to becoming pending\n"); | ||
|
|
||
| // Now loop until we see that SIGTERM is pending. | ||
| while (1) { | ||
| sigpending(&set); | ||
| if (sigismember(&set, SIGTERM)) { | ||
| printf("SIGTERM is now pending\n"); | ||
| pthread_mutex_lock(&lock); | ||
| is_pending = true; | ||
| pthread_cond_signal(&pending); | ||
| pthread_mutex_unlock(&lock); | ||
| break; | ||
| } | ||
| sleepms(1); | ||
| } | ||
|
|
||
| assert(!got_sigterm); | ||
|
|
||
| pthread_mutex_lock(&lock); | ||
| if (!unblock_signal) { | ||
| pthread_cond_wait(&unblock, &lock); | ||
| } | ||
| pthread_mutex_unlock(&lock); | ||
|
|
||
| // Now unlock all signals andwe should recieve SIGTERM here. | ||
sbc100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| printf("Unblocking signals\n"); | ||
| sigfillset(&set); | ||
| pthread_sigmask(SIG_UNBLOCK, &set, NULL); | ||
|
|
||
| assert(got_sigterm); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| int main() { | ||
| int ret; | ||
| setup_handler(); | ||
|
|
||
| pthread_mutex_lock(&lock); | ||
| ret = pthread_create(&child_thread, NULL, thread_start, 0); | ||
| assert(ret == 0); | ||
|
|
||
| // Wait until thread kicks in and sets the shared variable. | ||
| pthread_cond_wait(&started, &lock); | ||
| pthread_mutex_unlock(&lock); | ||
| printf("thread has started, sending SIGTERM\n"); | ||
|
|
||
| ret = pthread_kill(child_thread, SIGTERM); | ||
| assert(ret == 0); | ||
| printf("SIGTERM sent\n"); | ||
|
|
||
| pthread_mutex_lock(&lock); | ||
| if (!is_pending) { | ||
| pthread_cond_wait(&pending, &lock); | ||
| } | ||
|
|
||
| // Now the signal is pending on the child thread we block and unblock | ||
| // all signals on the mains thread, which should be a no-op | ||
sbc100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // We had a bug where pending signals were not stored in TLS which would | ||
| // cause this to raise the pending signals erronously here. | ||
| sigset_t set; | ||
| sigfillset(&set); | ||
| pthread_sigmask(SIG_BLOCK, &set, NULL); | ||
| pthread_sigmask(SIG_UNBLOCK, &set, NULL); | ||
|
|
||
| // Signal the child thread to unlock and recieve the signal | ||
| unblock_signal = true; | ||
| pthread_cond_signal(&unblock); | ||
| pthread_mutex_unlock(&lock); | ||
|
|
||
| pthread_join(child_thread, NULL); | ||
| printf("done\n"); | ||
| return 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
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.