2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-25 15:07:05 +00:00

ovs_threads: Avoid running pthread destructors from main thread exit.

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, causing pthread deadlocks).
Similar behavior has been seen by
other people as seen in the following email thread:
https://sourceware.org/ml/pthreads-win32/2003/msg00001.html

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@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Gurucharan Shetty
2015-04-07 17:34:27 -07:00
parent 3b4099b496
commit d2843eba6d
3 changed files with 31 additions and 0 deletions

View File

@@ -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);

View File

@@ -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"
@@ -668,6 +669,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.
*
@@ -684,6 +697,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);
}

View File

@@ -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();