[ovs-dev] [PATCH 2/2] ovs_threads: Avoid running pthread destructors from main thread exit.

Gurucharan Shetty shettyg at nicira.com
Wed Apr 8 01:06:48 UTC 2015


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 <gshetty at 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




More information about the dev mailing list