No need for this indirection via qemu_notify_event. On Unix, we already catch SIGALRM via signalfd (or its emulation) and run the handler synchronously. Under Win32, handlers run in separate threads. So we just need to grab the global lock around the handler execution.
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- The Unix side looks safe to me, but I'm not yet 100% confident about Win32. This is part of an ongoing effort to create separate alarm timers over their own io-threads. A lengthy effort. But these bits appear useful to me already. main-loop.c | 2 -- qemu-timer.c | 21 +++++++++++++-------- qemu-timer.h | 1 - 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/main-loop.c b/main-loop.c index eb3b6e6..1a6ea25 100644 --- a/main-loop.c +++ b/main-loop.c @@ -499,8 +499,6 @@ int main_loop_wait(int nonblocking) slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); #endif - qemu_run_all_timers(); - /* Check bottom-halves last in case any of the earlier events triggered them. */ qemu_bh_poll(); diff --git a/qemu-timer.c b/qemu-timer.c index 5aea94e..26411a2 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -441,7 +441,7 @@ uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts) return qemu_timer_pending(ts) ? ts->expire_time : -1; } -void qemu_run_all_timers(void) +static void qemu_run_all_timers(void) { alarm_timer->pending = false; @@ -457,11 +457,7 @@ void qemu_run_all_timers(void) } } -#ifdef _WIN32 -static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) -#else static void host_alarm_handler(int host_signum) -#endif { struct qemu_alarm_timer *t = alarm_timer; if (!t) @@ -469,7 +465,7 @@ static void host_alarm_handler(int host_signum) t->expired = true; t->pending = true; - qemu_notify_event(); + qemu_run_all_timers(); } #if defined(__linux__) @@ -613,9 +609,11 @@ static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, if (!t) { return; } + qemu_mutex_lock_iothread(); t->expired = true; t->pending = true; - qemu_notify_event(); + qemu_run_all_timers(); + qemu_mutex_unlock_iothread(); } static int mm_start_timer(struct qemu_alarm_timer *t) @@ -668,6 +666,13 @@ static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) } } +static void CALLBACK win32_alarm_handler(PVOID lpParam, BOOLEAN unused) +{ + qemu_mutex_lock_iothread(); + host_alarm_handler(0); + qemu_mutex_unlock_iothread(); +} + static int win32_start_timer(struct qemu_alarm_timer *t) { HANDLE hTimer; @@ -679,7 +684,7 @@ static int win32_start_timer(struct qemu_alarm_timer *t) interval in the dynticks case. */ success = CreateTimerQueueTimer(&hTimer, NULL, - host_alarm_handler, + win32_alarm_handler, t, 1, 3600000, diff --git a/qemu-timer.h b/qemu-timer.h index f8af595..b9bf313 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -58,7 +58,6 @@ bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time); uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts); void qemu_run_timers(QEMUClock *clock); -void qemu_run_all_timers(void); void configure_alarms(char const *opt); void init_clocks(void); int init_timer_alarm(void); -- 1.7.3.4