| From 2011e215a101ce928f81baae4ffa9d9ae817ce33 Mon Sep 17 00:00:00 2001 |
| From: Peter Hutterer <peter.hutterer@who-t.net> |
| Date: Fri, 27 Apr 2012 08:52:39 +0800 |
| Subject: [PATCH] os: make timers signal-safe |
| |
| If TimerSet() is called from a signal handler (synaptics tap handling code) |
| may result in list corruption if we're currently inside TimerSet(). |
| |
| See backtrace in |
| https://bugzilla.redhat.com/show_bug.cgi?id=814869 |
| |
| Block signals for all list manipulations in the timers. |
| |
| Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> |
| Reviewed-by: Chase Douglas <chase.douglas@canonical.com> |
| (cherry picked from commit 08962951de969b9d8c870af8b6e47303dc0decfd) |
| |
| Conflicts: |
| |
| os/WaitFor.c |
| --- |
| os/WaitFor.c | 18 ++++++++++++++++-- |
| 1 files changed, 16 insertions(+), 2 deletions(-) |
| |
| diff --git a/os/WaitFor.c b/os/WaitFor.c |
| index 867cb04..236406e 100644 |
| --- a/os/WaitFor.c |
| +++ b/os/WaitFor.c |
| @@ -405,6 +405,7 @@ CheckAllTimers(void) |
| OsTimerPtr timer; |
| CARD32 now; |
| |
| + OsBlockSignals(); |
| start: |
| now = GetTimeInMillis(); |
| |
| @@ -414,6 +415,7 @@ start: |
| goto start; |
| } |
| } |
| + OsReleaseSignals(); |
| } |
| |
| static void |
| @@ -421,11 +423,13 @@ DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) |
| { |
| CARD32 newTime; |
| |
| + OsBlockSignals(); |
| *prev = timer->next; |
| timer->next = NULL; |
| newTime = (*timer->callback)(timer, now, timer->arg); |
| if (newTime) |
| TimerSet(timer, 0, newTime, timer->callback, timer->arg); |
| + OsReleaseSignals(); |
| } |
| |
| OsTimerPtr |
| @@ -443,6 +447,7 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis, |
| } |
| else |
| { |
| + OsBlockSignals(); |
| for (prev = &timers; *prev; prev = &(*prev)->next) |
| { |
| if (*prev == timer) |
| @@ -453,6 +458,7 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis, |
| break; |
| } |
| } |
| + OsReleaseSignals(); |
| } |
| if (!millis) |
| return timer; |
| @@ -473,29 +479,35 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis, |
| if (!millis) |
| return timer; |
| } |
| + OsBlockSignals(); |
| for (prev = &timers; |
| *prev && (int) ((*prev)->expires - millis) <= 0; |
| prev = &(*prev)->next) |
| ; |
| timer->next = *prev; |
| *prev = timer; |
| + OsReleaseSignals(); |
| return timer; |
| } |
| |
| Bool |
| TimerForce(OsTimerPtr timer) |
| { |
| + int rc = FALSE; |
| OsTimerPtr *prev; |
| |
| + OsBlockSignals(); |
| for (prev = &timers; *prev; prev = &(*prev)->next) |
| { |
| if (*prev == timer) |
| { |
| DoTimer(timer, GetTimeInMillis(), prev); |
| - return TRUE; |
| + rc = TRUE; |
| + break; |
| } |
| } |
| - return FALSE; |
| + OsReleaseSignals(); |
| + return rc; |
| } |
| |
| |
| @@ -506,6 +518,7 @@ TimerCancel(OsTimerPtr timer) |
| |
| if (!timer) |
| return; |
| + OsBlockSignals(); |
| for (prev = &timers; *prev; prev = &(*prev)->next) |
| { |
| if (*prev == timer) |
| @@ -514,6 +527,7 @@ TimerCancel(OsTimerPtr timer) |
| break; |
| } |
| } |
| + OsReleaseSignals(); |
| } |
| |
| void |
| -- |
| 1.7.7.3 |
| |