From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:44528) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXyTL-0008FX-L8 for qemu-devel@nongnu.org; Tue, 06 Dec 2011 12:06:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RXyTF-0006BK-QM for qemu-devel@nongnu.org; Tue, 06 Dec 2011 12:06:27 -0500 Received: from mail-iy0-f173.google.com ([209.85.210.173]:42926) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RXyTF-00068U-FW for qemu-devel@nongnu.org; Tue, 06 Dec 2011 12:06:21 -0500 Received: by mail-iy0-f173.google.com with SMTP id j26so323826iaf.4 for ; Tue, 06 Dec 2011 09:06:21 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Tue, 6 Dec 2011 18:05:55 +0100 Message-Id: <1323191155-22549-5-git-send-email-pbonzini@redhat.com> In-Reply-To: <1323191155-22549-1-git-send-email-pbonzini@redhat.com> References: <1323191155-22549-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 4/4] ccid: make threads joinable List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: jan.kiszka@siemens.com, alevy@redhat.com Destroying a mutex that another thread might have just unlocked is racy. It usually works, but you cannot do that in general and can lead to deadlocks or segfaults. Change ccid to use joinable threads instead. (Also, qemu_mutex_init/qemu_cond_init were missing). Signed-off-by: Paolo Bonzini --- hw/ccid-card-emulated.c | 26 +++++++++++--------------- 1 files changed, 11 insertions(+), 15 deletions(-) diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c index 9fe9db5..2d2ebce 100644 --- a/hw/ccid-card-emulated.c +++ b/hw/ccid-card-emulated.c @@ -120,6 +120,7 @@ struct EmulatedState { uint8_t atr_length; QSIMPLEQ_HEAD(event_list, EmulEvent) event_list; QemuMutex event_list_mutex; + QemuThread event_thread_id; VReader *reader; QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list; QemuMutex vreader_mutex; /* and guest_apdu_list mutex */ @@ -127,8 +128,7 @@ struct EmulatedState { QemuCond handle_apdu_cond; int pipe[2]; int quit_apdu_thread; - QemuMutex apdu_thread_quit_mutex; - QemuCond apdu_thread_quit_cond; + QemuThread apdu_thread_id; }; static void emulated_apdu_from_guest(CCIDCardState *base, @@ -271,9 +271,6 @@ static void *handle_apdu_thread(void* arg) } qemu_mutex_unlock(&card->vreader_mutex); } - qemu_mutex_lock(&card->apdu_thread_quit_mutex); - qemu_cond_signal(&card->apdu_thread_quit_cond); - qemu_mutex_unlock(&card->apdu_thread_quit_mutex); return NULL; } @@ -489,7 +486,6 @@ static uint32_t parse_enumeration(char *str, static int emulated_initfn(CCIDCardState *base) { EmulatedState *card = DO_UPCAST(EmulatedState, base, base); - QemuThread thread_id; VCardEmulError ret; EnumTable *ptable; @@ -541,9 +537,10 @@ static int emulated_initfn(CCIDCardState *base) printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME); return -1; } - qemu_thread_create(&thread_id, event_thread, card, QEMU_THREAD_DETACHED); - qemu_thread_create(&thread_id, handle_apdu_thread, card, - QEMU_THREAD_DETACHED); + qemu_thread_create(&card->event_thread_id, event_thread, card, + QEMU_THREAD_JOINABLE); + qemu_thread_create(&card->apdu_thread_id, handle_apdu_thread, card, + QEMU_THREAD_JOINABLE); return 0; } @@ -553,15 +550,14 @@ static int emulated_exitfn(CCIDCardState *base) VEvent *vevent = vevent_new(VEVENT_LAST, NULL, NULL); vevent_queue_vevent(vevent); /* stop vevent thread */ - qemu_mutex_lock(&card->apdu_thread_quit_mutex); + qemu_thread_join(&card->event_thread_id); + card->quit_apdu_thread = 1; /* stop handle_apdu thread */ qemu_cond_signal(&card->handle_apdu_cond); - qemu_cond_wait(&card->apdu_thread_quit_cond, - &card->apdu_thread_quit_mutex); - /* handle_apdu thread stopped, can destroy all of it's mutexes */ + qemu_thread_join(&card->apdu_thread_id); + + /* threads exited, can destroy all condvars/mutexes */ qemu_cond_destroy(&card->handle_apdu_cond); - qemu_cond_destroy(&card->apdu_thread_quit_cond); - qemu_mutex_destroy(&card->apdu_thread_quit_mutex); qemu_mutex_destroy(&card->handle_apdu_mutex); qemu_mutex_destroy(&card->vreader_mutex); qemu_mutex_destroy(&card->event_list_mutex); -- 1.7.7.1