mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-17 21:26:13 -07:00
qemu-thread: add per-thread atexit functions
Destructors are the main additional feature of pthread TLS compared to __thread. If we were using C++ (hint, hint!) we could have used thread-local objects with a destructor. Since we are not, instead, we add a simple Notifier-based API. Note that the notifier must be per-thread as well. We can add a global list as well later, perhaps. The Win32 implementation has some complications because a) detached threads used not to have a QemuThreadData; b) the main thread does not go through win32_start_routine, so we have to use atexit too. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Message-id: 1417518350-6167-3-git-send-email-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
d1d1b206b0
commit
ef57137f1b
3 changed files with 78 additions and 11 deletions
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
#include "qemu/thread.h"
|
||||
#include "qemu/atomic.h"
|
||||
#include "qemu/notify.h"
|
||||
|
||||
static bool name_threads;
|
||||
|
||||
|
|
@ -401,6 +402,42 @@ void qemu_event_wait(QemuEvent *ev)
|
|||
}
|
||||
}
|
||||
|
||||
static pthread_key_t exit_key;
|
||||
|
||||
union NotifierThreadData {
|
||||
void *ptr;
|
||||
NotifierList list;
|
||||
};
|
||||
QEMU_BUILD_BUG_ON(sizeof(union NotifierThreadData) != sizeof(void *));
|
||||
|
||||
void qemu_thread_atexit_add(Notifier *notifier)
|
||||
{
|
||||
union NotifierThreadData ntd;
|
||||
ntd.ptr = pthread_getspecific(exit_key);
|
||||
notifier_list_add(&ntd.list, notifier);
|
||||
pthread_setspecific(exit_key, ntd.ptr);
|
||||
}
|
||||
|
||||
void qemu_thread_atexit_remove(Notifier *notifier)
|
||||
{
|
||||
union NotifierThreadData ntd;
|
||||
ntd.ptr = pthread_getspecific(exit_key);
|
||||
notifier_remove(notifier);
|
||||
pthread_setspecific(exit_key, ntd.ptr);
|
||||
}
|
||||
|
||||
static void qemu_thread_atexit_run(void *arg)
|
||||
{
|
||||
union NotifierThreadData ntd = { .ptr = arg };
|
||||
notifier_list_notify(&ntd.list, NULL);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) qemu_thread_atexit_init(void)
|
||||
{
|
||||
pthread_key_create(&exit_key, qemu_thread_atexit_run);
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to set the threads name; note that this is for debug, so
|
||||
* we're not going to fail if we can't set it.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue