[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