summaryrefslogtreecommitdiffstats
path: root/Timer.st
diff options
context:
space:
mode:
Diffstat (limited to 'Timer.st')
-rw-r--r--Timer.st35
1 files changed, 15 insertions, 20 deletions
diff --git a/Timer.st b/Timer.st
index 438d2de..a5d3e93 100644
--- a/Timer.st
+++ b/Timer.st
@@ -56,7 +56,13 @@ Object subclass: Timer [
cancel [
<category: 'management'>
- schedule removeTimer: self.
+ "Remember that the timer is gone."
+ schedule := nil.
+ ]
+
+ isCanceled [
+ <category: 'management'>
+ ^ schedule == nil.
]
]
@@ -111,13 +117,6 @@ bit difficult to do this race free.'>
^ sched
]
- removeTimer: aSched [
- <category: 'schedule'>
- sem critical: [
- queue remove: aSched ifAbsent: [].
- ].
- ]
-
runTimers [
<category: 'delay_loop'>
@@ -131,24 +130,20 @@ bit difficult to do this race free.'>
fireTimers: now [
<category: 'private'>
- | copy |
-
- "Create a shallow copy of the data"
- copy := sem critical: [queue copy].
"Now execute the timers. One way or another this is crazy. If we have
a long blocking application or a deadlock the timer queue will get
stuck. But if we run this in a new process a later process might be run
before this process, changing the order of the timers."
- copy do: [:each |
- each timeout > now ifTrue: [^true].
- sem critical: [queue remove: each].
- [
- each fire
- ] on: Error do: [:e |
+ "Only this process will remove items, this is why we can check isEmpty
+ without having the lock"
+ [queue isEmpty or: [queue first timeout > now]] whileFalse: [ | each |
+ each := sem critical: [queue removeFirst].
+ each isCanceled ifFalse: [
+ [each fire] on: Error do: [:e |
e logException: 'Execution of timer failed: %1' % {e tag} area: #timer.
- ].
- ].
+ ]].
+ ]
]
]