-
Notifications
You must be signed in to change notification settings - Fork 461
chore: extra pthread handling safety #2390
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
base: main
Are you sure you want to change the base?
Changes from 3 commits
1cc9346
1f2963e
0e70661
c669951
3875ca2
2920b0d
57cdd5c
91546cd
197cc9b
4360649
1179026
f870e84
e0773a0
87908bc
b4eb528
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,7 +95,12 @@ __thread HashTable *sandboxed_env = NULL; | |
|
|
||
| #ifndef PHP_WIN32 | ||
| static bool is_forked_child = false; | ||
| static void frankenphp_fork_child(void) { is_forked_child = true; } | ||
| static void frankenphp_fork_child(void) { | ||
| is_forked_child = true; | ||
| #ifdef __linux__ | ||
| prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there's an equivalent to this in macOS or BSD? realistically speaking, it's hard to imagine this ever kicks in if a php object destructor waits on the child pid, but in case the php runtime throws an unrecoverable error in a destructor, it might exit the thread without calling the destructor responsible for signalling and cleaning up the child
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that this syscall can race. Here is a workaround: https://stackoverflow.com/a/59216119 On FreeBSD, you can do this: On macOS, it's harder; you have to run kqueue and way more code.
henderkes marked this conversation as resolved.
Outdated
|
||
| #endif | ||
| } | ||
| #endif | ||
|
|
||
| /* Best-effort force-kill for stuck PHP threads. | ||
|
|
@@ -916,6 +921,12 @@ static int frankenphp_startup(sapi_module_struct *sapi_module) { | |
| static int frankenphp_deactivate(void) { return SUCCESS; } | ||
|
|
||
| static size_t frankenphp_ub_write(const char *str, size_t str_length) { | ||
| #ifndef PHP_WIN32 | ||
| if (UNEXPECTED(is_forked_child)) { | ||
| return 0; | ||
| } | ||
| #endif | ||
|
|
||
| struct go_ub_write_return result = | ||
| go_ub_write(thread_index, (char *)str, str_length); | ||
|
|
||
|
|
@@ -927,6 +938,12 @@ static size_t frankenphp_ub_write(const char *str, size_t str_length) { | |
| } | ||
|
|
||
| static int frankenphp_send_headers(sapi_headers_struct *sapi_headers) { | ||
| #ifndef PHP_WIN32 | ||
| if (UNEXPECTED(is_forked_child)) { | ||
| return SAPI_HEADER_SEND_FAILED; | ||
| } | ||
| #endif | ||
|
|
||
| if (SG(request_info).no_headers == 1) { | ||
| return SAPI_HEADER_SENT_SUCCESSFULLY; | ||
| } | ||
|
|
@@ -952,6 +969,12 @@ static int frankenphp_send_headers(sapi_headers_struct *sapi_headers) { | |
| } | ||
|
|
||
| static void frankenphp_sapi_flush(void *server_context) { | ||
| #ifndef PHP_WIN32 | ||
| if (UNEXPECTED(is_forked_child)) { | ||
| return; | ||
| } | ||
| #endif | ||
|
|
||
| sapi_send_headers(); | ||
| if (go_sapi_flush(thread_index)) { | ||
| php_handle_aborted_connection(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.