From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57704) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VF1Np-0003rv-TV for qemu-devel@nongnu.org; Thu, 29 Aug 2013 08:31:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VF1Nh-0002E1-8U for qemu-devel@nongnu.org; Thu, 29 Aug 2013 08:31:29 -0400 Received: from mail-ea0-x22a.google.com ([2a00:1450:4013:c01::22a]:39061) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VF1Nh-0002Dl-2C for qemu-devel@nongnu.org; Thu, 29 Aug 2013 08:31:21 -0400 Received: by mail-ea0-f170.google.com with SMTP id h14so212811eak.1 for ; Thu, 29 Aug 2013 05:31:20 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Thu, 29 Aug 2013 14:31:00 +0200 Message-Id: <1377779462-24383-3-git-send-email-pbonzini@redhat.com> In-Reply-To: <1377779462-24383-1-git-send-email-pbonzini@redhat.com> References: <1377779462-24383-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [RFC PATCH 2/3] qemu-timer: fix race conditions on freeing the timer List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: qemulist@gmail.com, stefanha@redhat.com Save the callback and opaque before releasing the mutex, because the timer could be freed while we do not take the mutex. Related to this, ensure the timer is not active before freeing it. Signed-off-by: Paolo Bonzini --- qemu-timer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index d650247..aa22801 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -316,6 +316,7 @@ void timer_init(QEMUTimer *ts, void timer_free(QEMUTimer *ts) { + timer_del(ts); g_free(ts); } @@ -410,7 +411,9 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) QEMUTimer *ts; int64_t current_time; bool progress = false; - + QEMUTimerCB *cb; + void *opaque; + if (!timer_list->clock->enabled) { return progress; } @@ -423,13 +426,16 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) qemu_mutex_unlock(&timer_list->active_timers_lock); break; } + /* remove timer from the list before calling the callback */ timer_list->active_timers = ts->next; ts->next = NULL; + cb = ts->cb; + opaque = ts->opaque; qemu_mutex_unlock(&timer_list->active_timers_lock); /* run the callback (the timer list can be modified) */ - ts->cb(ts->opaque); + cb(opaque); progress = true; } return progress; -- 1.8.3.1