diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-11-21 22:26:29 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-11-21 22:31:30 +0400 |
commit | 0a420dc3f8b69a5675b504f7975d170ee79f1ee2 (patch) | |
tree | 21475965be9b38a050f22afbaf90b9cdf9b94026 /win32_threads.c | |
parent | ff93a74691be86ed6ae4f9572a028e7eb9e5c944 (diff) | |
download | bdwgc-0a420dc3f8b69a5675b504f7975d170ee79f1ee2.tar.gz |
Add manual POSIX fork handling support (Android)
* include/gc.h (GC_set_handle_fork): Update comment.
* include/gc.h (GC_atfork_prepare, GC_atfork_parent, GC_atfork_child):
New API proto.
* include/private/gc_priv.h (GC_handle_fork): Change type from GC_bool
to int (to hold a value of -1).
* misc.c (GC_handle_fork): Likewise.
* include/private/gc_priv.h (GC_handle_fork): Add comment.
* misc.c (GC_set_handle_fork): Likewise.
* include/private/gcconfig.h (CAN_HANDLE_FORK): Define also for HURD
and PLATFORM_ANDROID; do not define if HAVE_NO_FORK already defined.
* include/private/gcconfig.h (CAN_CALL_ATFORK): New macro (defined if
CAN_HANDLE_FORK but not HURD or PLATFORM_ANDROID).
* include/private/gcconfig.h (HAVE_NO_FORK): New macro (defined for
Win32, OS/2 and others).
* misc.c (GC_atfork_prepare, GC_atfork_parent, GC_atfork_child): New
API function definition (only if not CAN_HANDLE_FORK and not
HAVE_NO_FORK).
* misc.c (GC_handle_fork): Map all negative values of argument except
for -1 to a positive one stored to GC_handle_fork; call GC_init to
initialize GC_stderr before ABORT invocation (only if not
SMALL_CONFIG).
* pthread_support.c (GC_atfork_prepare, GC_atfork_parent,
GC_atfork_child): New API function definition (only if
CAN_HANDLE_FORK).
* win32_threads.c (GC_atfork_prepare, GC_atfork_parent,
GC_atfork_child): Likewise.
* pthread_support.c (GC_thr_init): No pthread_atfork call if not
CAN_CALL_ATFORK; adjust GC_handle_fork value if pthread_atfork
succeeds; do not about in case of pthread_atfork failure provided
GC_handle_fork is -1 (only if CAN_HANDLE_FORK).
* win32_threads.c (GC_thr_init): Likewise.
* tests/test.c (TEST_FORK_WITHOUT_ATFORK): Recognize new macro (do not
define NO_TEST_HANDLE_FORK in this case and set INIT_FORK_SUPPORT to
no-op).
* tests/test.c (INIT_FORK_SUPPORT): Define to GC_set_handle_fork(-1)
unless HANDLE_FORK, or NO_TEST_HANDLE_FORK or TEST_FORK_WITHOUT_ATFORK.
* tests/test.c (run_one_test): Surround fork() invocation with
GC_atfork_prepare, GC_atfork_parent, GC_atfork_child calls.
* win32_threads.c: Include unistd.h if CAN_CALL_ATFORK defined
(instead of CAN_HANDLE_FORK) to get pthread_atfork prototype.
Diffstat (limited to 'win32_threads.c')
-rw-r--r-- | win32_threads.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/win32_threads.c b/win32_threads.c index 4e25bc71..83b2c420 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -60,7 +60,7 @@ STATIC void GC_thread_exit_proc(void *arg); # include <pthread.h> -# ifdef CAN_HANDLE_FORK +# ifdef CAN_CALL_ATFORK # include <unistd.h> # endif @@ -1085,6 +1085,25 @@ GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn, GC_remove_all_threads_but_me(); UNLOCK(); } + + /* Routines for fork handling by client (no-op if pthread_atfork works). */ + GC_API void GC_CALL GC_atfork_prepare(void) + { + if (GC_handle_fork <= 0) + fork_prepare_proc(); + } + + GC_API void GC_CALL GC_atfork_parent(void) + { + if (GC_handle_fork <= 0) + fork_parent_proc(); + } + + GC_API void GC_CALL GC_atfork_child(void) + { + if (GC_handle_fork <= 0) + fork_child_proc(); + } #endif /* CAN_HANDLE_FORK */ void GC_push_thread_structures(void) @@ -2404,10 +2423,17 @@ GC_INNER void GC_thr_init(void) # ifdef CAN_HANDLE_FORK /* Prepare for forks if requested. */ - if (GC_handle_fork - && pthread_atfork(fork_prepare_proc, fork_parent_proc, - fork_child_proc) != 0) - ABORT("pthread_atfork failed"); + if (GC_handle_fork) { +# ifdef CAN_CALL_ATFORK + if (pthread_atfork(fork_prepare_proc, fork_parent_proc, + fork_child_proc) == 0) { + /* Handlers successfully registered. */ + GC_handle_fork = 1; + } else +# endif + /* else */ if (GC_handle_fork != -1) + ABORT("pthread_atfork failed"); + } # endif /* Add the initial thread, so we can stop it. */ |