diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2015-01-13 13:49:18 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2015-01-13 13:49:18 +0000 |
| commit | a00369fc565cef32076b767ecff34469642afe06 (patch) | |
| tree | 23d3ec45c6fad01610b4fe9dfa1cf49eaae38f97 /util/qemu-thread-win32.c | |
| parent | 7d5ad15d17f26dd4f9ff5f3491828bc34e74f28c (diff) | |
| parent | 07d31d07f4b28a61b65cec95da69851c675f20b9 (diff) | |
| download | focaccia-qemu-a00369fc565cef32076b767ecff34469642afe06.tar.gz focaccia-qemu-a00369fc565cef32076b767ecff34469642afe06.zip | |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
# gpg: Signature made Tue 13 Jan 2015 13:48:06 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
* remotes/stefanha/tags/block-pull-request: (38 commits)
NVMe: Set correct VS Value for 1.1 Compliant Controllers
MAINTAINERS: Add migration/block* to block subsystem
MAINTAINERS: Update email addresses for Chrysostomos Nanakos
nvme: Fix get/set number of queues feature
ide: Implement VPD response for ATAPI
block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE, TARGET}
block: limited request size in write zeroes unsupported path
coroutine: try harder not to delete coroutines
coroutine: drop qemu_coroutine_adjust_pool_size
coroutine: rewrite pool to avoid mutex
QSLIST: add lock-free operations
test-coroutine: avoid overflow on 32-bit systems
qemu-thread: add per-thread atexit functions
coroutine-ucontext: use __thread
qemu-iotests: Add supported os parameter for python tests
qemu-iotests: Add "_supported_os Linux" to 058
qemu-iotests: Replace "/bin/true" with "true"
.gitignore: Ignore generated "common.env"
libqos: Convert malloc-pc allocator to a generic allocator
migration/block: fix pending() return value
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/qemu-thread-win32.c')
| -rw-r--r-- | util/qemu-thread-win32.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index c405c9bef6..406b52f91d 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -12,6 +12,7 @@ */ #include "qemu-common.h" #include "qemu/thread.h" +#include "qemu/notify.h" #include <process.h> #include <assert.h> #include <limits.h> @@ -268,6 +269,7 @@ struct QemuThreadData { void *(*start_routine)(void *); void *arg; short mode; + NotifierList exit; /* Only used for joinable threads. */ bool exited; @@ -275,18 +277,40 @@ struct QemuThreadData { CRITICAL_SECTION cs; }; +static bool atexit_registered; +static NotifierList main_thread_exit; + static __thread QemuThreadData *qemu_thread_data; +static void run_main_thread_exit(void) +{ + notifier_list_notify(&main_thread_exit, NULL); +} + +void qemu_thread_atexit_add(Notifier *notifier) +{ + if (!qemu_thread_data) { + if (!atexit_registered) { + atexit_registered = true; + atexit(run_main_thread_exit); + } + notifier_list_add(&main_thread_exit, notifier); + } else { + notifier_list_add(&qemu_thread_data->exit, notifier); + } +} + +void qemu_thread_atexit_remove(Notifier *notifier) +{ + notifier_remove(notifier); +} + static unsigned __stdcall win32_start_routine(void *arg) { QemuThreadData *data = (QemuThreadData *) arg; void *(*start_routine)(void *) = data->start_routine; void *thread_arg = data->arg; - if (data->mode == QEMU_THREAD_DETACHED) { - g_free(data); - data = NULL; - } qemu_thread_data = data; qemu_thread_exit(start_routine(thread_arg)); abort(); @@ -296,12 +320,14 @@ void qemu_thread_exit(void *arg) { QemuThreadData *data = qemu_thread_data; - if (data) { - assert(data->mode != QEMU_THREAD_DETACHED); + notifier_list_notify(&data->exit, NULL); + if (data->mode == QEMU_THREAD_JOINABLE) { data->ret = arg; EnterCriticalSection(&data->cs); data->exited = true; LeaveCriticalSection(&data->cs); + } else { + g_free(data); } _endthreadex(0); } @@ -313,9 +339,10 @@ void *qemu_thread_join(QemuThread *thread) HANDLE handle; data = thread->data; - if (!data) { + if (data->mode == QEMU_THREAD_DETACHED) { return NULL; } + /* * Because multiple copies of the QemuThread can exist via * qemu_thread_get_self, we need to store a value that cannot @@ -329,7 +356,6 @@ void *qemu_thread_join(QemuThread *thread) CloseHandle(handle); } ret = data->ret; - assert(data->mode != QEMU_THREAD_DETACHED); DeleteCriticalSection(&data->cs); g_free(data); return ret; @@ -347,6 +373,7 @@ void qemu_thread_create(QemuThread *thread, const char *name, data->arg = arg; data->mode = mode; data->exited = false; + notifier_list_init(&data->exit); if (data->mode != QEMU_THREAD_DETACHED) { InitializeCriticalSection(&data->cs); @@ -358,7 +385,7 @@ void qemu_thread_create(QemuThread *thread, const char *name, error_exit(GetLastError(), __func__); } CloseHandle(hThread); - thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data; + thread->data = data; } void qemu_thread_get_self(QemuThread *thread) @@ -373,11 +400,10 @@ HANDLE qemu_thread_get_handle(QemuThread *thread) HANDLE handle; data = thread->data; - if (!data) { + if (data->mode == QEMU_THREAD_DETACHED) { return NULL; } - assert(data->mode != QEMU_THREAD_DETACHED); EnterCriticalSection(&data->cs); if (!data->exited) { handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE, |