diff --git a/include/aws/common/private/thread_shared.h b/include/aws/common/private/thread_shared.h index ca263e56c..19e648319 100644 --- a/include/aws/common/private/thread_shared.h +++ b/include/aws/common/private/thread_shared.h @@ -36,4 +36,9 @@ AWS_COMMON_API void aws_thread_initialize_thread_management(void); */ AWS_COMMON_API size_t aws_thread_get_managed_thread_count(void); +/** + * The handler before fork in the parent process. + */ +void aws_pthread_atfork_on_fork_prepare(void); + #endif /* AWS_COMMON_PRIVATE_THREAD_SHARED_H */ diff --git a/source/common.c b/source/common.c index a391f4fcb..eed29174b 100644 --- a/source/common.c +++ b/source/common.c @@ -390,6 +390,12 @@ void aws_common_library_init(struct aws_allocator *allocator) { AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "static: libnuma.so failed to load"); } #endif + +#ifndef AWS_OS_WINDOWS + if (pthread_atfork(aws_pthread_atfork_on_fork_prepare, NULL, NULL) != 0) { + AWS_LOGF_INFO(AWS_LS_COMMON_GENERAL, "static: failed to register pthread at fork"); + } +#endif } } diff --git a/source/posix/cross_process_lock.c b/source/posix/cross_process_lock.c index 1ef5d2b5f..f94834184 100644 --- a/source/posix/cross_process_lock.c +++ b/source/posix/cross_process_lock.c @@ -133,7 +133,6 @@ struct aws_cross_process_lock *aws_cross_process_lock_try_acquire( void aws_cross_process_lock_release(struct aws_cross_process_lock *instance_lock) { if (instance_lock) { - flock(instance_lock->locked_fd, LOCK_UN); close(instance_lock->locked_fd); AWS_LOGF_TRACE(AWS_LS_COMMON_GENERAL, "static: Lock file released for fd %d", instance_lock->locked_fd); aws_mem_release(instance_lock->allocator, instance_lock); diff --git a/source/thread_shared.c b/source/thread_shared.c index bd479a16e..e3c414aaf 100644 --- a/source/thread_shared.c +++ b/source/thread_shared.c @@ -165,3 +165,19 @@ void aws_thread_pending_join_add(struct aws_linked_list_node *node) { void aws_thread_initialize_thread_management(void) { aws_linked_list_init(&s_pending_join_managed_threads); } + +void aws_pthread_atfork_on_fork_prepare(void) { + /** + * The handler before fork in the parent process. + * + * Clean up the s_pending_join_managed_threads now, the list is created by the parent process and should not be used + * in child process. + * Fork will copy the list, but not the real threads. + */ + struct aws_linked_list empty; + aws_linked_list_init(&empty); + aws_mutex_lock(&s_managed_thread_lock); + aws_linked_list_swap_contents(&empty, &s_pending_join_managed_threads); + aws_mutex_unlock(&s_managed_thread_lock); + aws_thread_join_and_free_wrapper_list(&empty); +}