Windows uses pthreads-win32 library to provide the Linux pthread functionality. It is observed that when the main thread calls a pthread destructor after it exits, undefined behavior is seen (e.g., junk values in data).
To avoid this, this commit de-registers the thread destructor when the main thread exits (via the atexit handler). Signed-off-by: Gurucharan Shetty <gshe...@nicira.com> --- lib/ovs-rcu.c | 14 ++++++++++++++ lib/ovs-thread.c | 15 +++++++++++++++ tests/test-atomic.c | 2 ++ 3 files changed, 31 insertions(+) diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c index 76659bb..e0634cf 100644 --- a/lib/ovs-rcu.c +++ b/lib/ovs-rcu.c @@ -16,6 +16,7 @@ #include <config.h> #include "ovs-rcu.h" +#include "fatal-signal.h" #include "guarded-list.h" #include "list.h" #include "ovs-thread.h" @@ -313,6 +314,18 @@ ovsrcu_thread_exit_cb(void *perthread) ovsrcu_unregister__(perthread); } +/* Cancels the callback to ovsrcu_thread_exit_cb(). + * + * Cancelling the call to the destructor during the main thread exit + * is needed while using pthreads-win32 library in Windows. It has been + * observed that in pthreads-win32, a call to the destructor during + * main thread exit causes undefined behavior. */ +static void +ovsrcu_cancel_thread_exit_cb(void *aux OVS_UNUSED) +{ + pthread_setspecific(perthread_key, NULL); +} + static void ovsrcu_init_module(void) { @@ -320,6 +333,7 @@ ovsrcu_init_module(void) if (ovsthread_once_start(&once)) { global_seqno = seq_create(); xpthread_key_create(&perthread_key, ovsrcu_thread_exit_cb); + fatal_signal_add_hook(ovsrcu_cancel_thread_exit_cb, NULL, NULL, true); list_init(&ovsrcu_threads); ovs_mutex_init(&ovsrcu_threads_mutex); diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c index 7d38c80..ca606d9 100644 --- a/lib/ovs-thread.c +++ b/lib/ovs-thread.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <unistd.h> #include "compiler.h" +#include "fatal-signal.h" #include "hash.h" #include "list.h" #include "netdev-dpdk.h" @@ -670,6 +671,18 @@ ovsthread_key_destruct__(void *slots_) free(slots); } +/* Cancels the callback to ovsthread_key_destruct__(). + * + * Cancelling the call to the destructor during the main thread exit + * is needed while using pthreads-win32 library in Windows. It has been + * observed that in pthreads-win32, a call to the destructor during + * main thread exit causes undefined behavior. */ +static void +ovsthread_cancel_ovsthread_key_destruct__(void *aux OVS_UNUSED) +{ + pthread_setspecific(tsd_key, NULL); +} + /* Initializes '*keyp' as a thread-specific data key. The data items are * initially null in all threads. * @@ -686,6 +699,8 @@ ovsthread_key_create(ovsthread_key_t *keyp, void (*destructor)(void *)) if (ovsthread_once_start(&once)) { xpthread_key_create(&tsd_key, ovsthread_key_destruct__); + fatal_signal_add_hook(ovsthread_cancel_ovsthread_key_destruct__, + NULL, NULL, true); ovsthread_once_done(&once); } diff --git a/tests/test-atomic.c b/tests/test-atomic.c index 50b3b7a..2af6a26 100644 --- a/tests/test-atomic.c +++ b/tests/test-atomic.c @@ -16,6 +16,7 @@ #include <config.h> #undef NDEBUG +#include "fatal-signal.h" #include "ovs-atomic.h" #include "ovstest.h" #include "ovs-thread.h" @@ -413,6 +414,7 @@ test_atomic_seq_cst(void) static void test_atomic_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { + fatal_signal_init(); test_atomic_plain(); test_atomic_relaxed(); test_atomic_consume(); -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev