Skip to content

Commit 3add470

Browse files
authored
Move pthread_cancel to native code. NFC. (#15603)
1 parent 3207244 commit 3add470

File tree

5 files changed

+22
-29
lines changed

5 files changed

+22
-29
lines changed

src/library_pthread.js

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,11 @@ var LibraryPThread = {
408408
},
409409

410410
__emscripten_thread_cleanup: function(thread) {
411+
// Called when a thread needs to be cleaned up so it can be reused.
412+
// A thread is considered reusable when it either returns from its
413+
// entry point, calls pthread_exit, or acts upon a cancellation.
414+
// Detached threads are responsible for calling this themselves,
415+
// otherwise pthread_join is responsible for calling this.
411416
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread);
412417
else postMessage({ 'cmd': 'cleanupThread', 'thread': thread });
413418
},
@@ -751,12 +756,12 @@ var LibraryPThread = {
751756
#endif
752757
},
753758

754-
pthread_kill__deps: ['$killThread', 'emscripten_main_browser_thread_id'],
759+
pthread_kill__deps: ['emscripten_main_browser_thread_id'],
755760
pthread_kill: function(thread, signal) {
756761
if (signal < 0 || signal >= 65/*_NSIG*/) return {{{ cDefine('EINVAL') }}};
757762
if (thread === _emscripten_main_browser_thread_id()) {
758763
if (signal == 0) return 0; // signal == 0 is a no-op.
759-
err('Main thread (id=' + thread + ') cannot be killed with pthread_kill!');
764+
err('Main thread (id=0x' + thread.toString(16) + ') cannot be killed with pthread_kill!');
760765
return {{{ cDefine('ESRCH') }}};
761766
}
762767
if (!thread) {
@@ -765,38 +770,19 @@ var LibraryPThread = {
765770
}
766771
var self = {{{ makeGetValue('thread', C_STRUCTS.pthread.self, 'i32') }}};
767772
if (self !== thread) {
768-
err('pthread_kill attempted on thread ' + thread + ', which does not point to a valid thread, or does not exist anymore!');
773+
err('pthread_kill attempted on thread 0x' + thread.toString(16) + ', which does not point to a valid thread, or does not exist anymore!');
769774
return {{{ cDefine('ESRCH') }}};
770775
}
771-
if (signal != 0) {
776+
if (signal === {{{ cDefine('SIGCANCEL') }}}) { // Used by pthread_cancel in musl
777+
if (!ENVIRONMENT_IS_PTHREAD) cancelThread(thread);
778+
else postMessage({ 'cmd': 'cancelThread', 'thread': thread });
779+
} else if (signal != 0) {
772780
if (!ENVIRONMENT_IS_PTHREAD) killThread(thread);
773-
else postMessage({ 'cmd': 'killThread', 'thread': thread});
781+
else postMessage({ 'cmd': 'killThread', 'thread': thread });
774782
}
775783
return 0;
776784
},
777785

778-
pthread_cancel__deps: ['$cancelThread', 'emscripten_main_browser_thread_id'],
779-
pthread_cancel: function(thread) {
780-
if (thread === _emscripten_main_browser_thread_id()) {
781-
err('Main thread (id=' + thread + ') cannot be canceled!');
782-
return {{{ cDefine('ESRCH') }}};
783-
}
784-
if (!thread) {
785-
err('pthread_cancel attempted on a null thread pointer!');
786-
return {{{ cDefine('ESRCH') }}};
787-
}
788-
var self = {{{ makeGetValue('thread', C_STRUCTS.pthread.self, 'i32') }}};
789-
if (self !== thread) {
790-
err('pthread_cancel attempted on thread ' + thread + ', which does not point to a valid thread, or does not exist anymore!');
791-
return {{{ cDefine('ESRCH') }}};
792-
}
793-
// Signal the thread that it needs to cancel itself.
794-
Atomics.store(HEAPU32, (thread + {{{ C_STRUCTS.pthread.cancel }}}) >> 2, 1);
795-
if (!ENVIRONMENT_IS_PTHREAD) cancelThread(thread);
796-
else postMessage({ 'cmd': 'cancelThread', 'thread': thread});
797-
return 0;
798-
},
799-
800786
// Returns 0 on success, or one of the values -ETIMEDOUT, -EWOULDBLOCK or -EINVAL on error.
801787
_emscripten_futex_wait_non_blocking__deps: ['emscripten_main_thread_process_queued_calls'],
802788
_emscripten_futex_wait_non_blocking: function(addr, val, timeout) {

src/struct_info_internal.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
"timeSpentInStatus",
3030
"name"
3131
]
32-
}
32+
},
33+
"defines": [
34+
"SIGCANCEL"
35+
]
3336
},
3437
{
3538
"file": "dynlink.h",

system/lib/libc/musl/src/thread/pthread_cancel.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "pthread_impl.h"
44
#include "syscall.h"
55

6+
#ifndef __EMSCRIPTEN__
67
hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
78

89
long __cancel()
@@ -83,14 +84,17 @@ static void init_cancellation()
8384
memset(&sa.sa_mask, -1, _NSIG/8);
8485
__libc_sigaction(SIGCANCEL, &sa, 0);
8586
}
87+
#endif
8688

8789
int pthread_cancel(pthread_t t)
8890
{
91+
#ifndef __EMSCRIPTEN__
8992
static int init;
9093
if (!init) {
9194
init_cancellation();
9295
init = 1;
9396
}
97+
#endif
9498
a_store(&t->cancel, 1);
9599
if (t == pthread_self()) {
96100
if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync)

tests/reference_struct_info.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@
322322
"SEEK_END": 2,
323323
"SEEK_SET": 0,
324324
"SIGALRM": 14,
325+
"SIGCANCEL": 33,
325326
"SOCK_CLOEXEC": 524288,
326327
"SOCK_DGRAM": 2,
327328
"SOCK_NONBLOCK": 2048,

tools/system_libs.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,6 @@ def get_files(self):
823823
# TODO: Support this. See #12216.
824824
'pthread_setname_np.c',
825825
# TODO: These could be moved away from JS in the upcoming musl upgrade.
826-
'pthread_cancel.c',
827826
'pthread_join.c', 'pthread_testcancel.c',
828827
]
829828
libc_files += files_in_path(

0 commit comments

Comments
 (0)