qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH for-3.1 2/2] util/qemu-thread-posix: Fix qemu_th


From: Eric Blake
Subject: Re: [Qemu-devel] [PATCH for-3.1 2/2] util/qemu-thread-posix: Fix qemu_thread_atexit* for OSX
Date: Mon, 5 Nov 2018 10:13:25 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1

On 11/5/18 7:55 AM, Peter Maydell wrote:
Our current implementation of qemu_thread_atexit* is broken on OSX.
This is because it works by cerating a piece of thread-specific

s/cerating/creating/

data with pthread_key_create() and using the destructor function
for that data to run the notifier function passed to it by
the caller of qemu_thread_atexit_add(). The expected use case
is that the caller uses a __thread variable as the notifier,
and uses the callback to clean up information that it is
keeping per-thread in __thread variables.

Unfortunately, on OSX this does not work, because on OSX
a __thread variable may be destroyed (freed) before the
pthread_key_create() destructor runs. (POSIX imposes no
ordering constraint here; the OSX implementation happens
to implement __thread variables in terms of pthread_key_create((),
whereas Linux uses different mechanisms that mean the __thread
variables will still be present when the pthread_key_create()
destructor is run.)

Fix this by switching to a scheme similar to the one qemu-thread-win32
uses for qemu_thread_atexit: keep the thread's notifiers on a
__thread variable, and run the notifiers on calls to
qemu_thread_exit() and on return from the start routine passed
to qemu_thread_start(). We do this with the pthread_cleanup_push()
API.

We take advantage of the qemu_thread_atexit_add() API
permission not to run thread notifiers on process exit to
avoid having to special case the main thread.

Suggested-by: Paolo Bonzini <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
qemu-thread-win32.c tries to handle the "main thread" case
by using an atexit() handler to run its notifiers. I don't
think this will work because the atexit handler may not run
on the main thread, in which case notify callback functions
which refer to __thread variables will get the wrong ones.
---
  util/qemu-thread-posix.c | 44 ++++++++++++++++++----------------------
  1 file changed, 20 insertions(+), 24 deletions(-)


@@ -501,7 +494,10 @@ static void *qemu_thread_start(void *args)
  #endif
      g_free(qemu_thread_args->name);
      g_free(qemu_thread_args);
-    return start_routine(arg);
+    pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
+    r = start_routine(arg);
+    pthread_cleanup_pop(1);
+    return r;
  }
void qemu_thread_create(QemuThread *thread, const char *name,


Reviewed-by: Eric Blake <address@hidden>

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



reply via email to

[Prev in Thread] Current Thread [Next in Thread]