diff options
author | Peter Zhu <[email protected]> | 2025-06-11 16:21:11 -0400 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2025-06-12 15:23:50 -0400 |
commit | 6e36841dbd5f52b572b690b8a4c3c534fec43ba8 () | |
tree | 2321618948f676c2b5d9628a9744bf8e9e0583db /thread_win32.c | |
parent | 5ec9a392cdf7f971221dc073dd466bce877d8acb (diff) |
Free rb_native_thread memory at fork
We never freed any resources of rb_native_thread at fork because it would cause it to hang. This is because it called rb_native_cond_destroy for condition variables. We can't call rb_native_cond_destroy here because according to the specs of pthread_cond_destroy: Attempting to destroy a condition variable upon which other threads are currently blocked results in undefined behavior. Specifically, glibc's pthread_cond_destroy waits on all the other listeners. Since after forking all the threads are dead, the condition variable's listeners will never wake up, so it will hang forever. This commit changes it to only free the memory and none of the condition variables.
Notes: Merged: https://.com/ruby/ruby/pull/13591
-rw-r--r-- | thread_win32.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -617,6 +617,12 @@ native_thread_init_stack(rb_thread_t *th, void *local_in_parent_frame) th->ec->machine.stack_maxsize = size - space; } #ifndef InterlockedExchangePointer #define InterlockedExchangePointer(t, v) \ (void *)InterlockedExchange((long *)(t), (long)(v)) |