Browse files

Prevent possible race conditions in scheduler.

  • Loading branch information...
1 parent 32eef54 commit 9723e14a4d1edafeb17551c5700e1053f1a980f6 @ProgVal ProgVal committed Jun 9, 2012
Showing with 16 additions and 8 deletions.
  1. +16 −8 src/schedule.py
View
24 src/schedule.py
@@ -32,8 +32,11 @@
Supybot driver.
"""
+from __future__ import with_statement
+
import time
import heapq
+from threading import Lock
import supybot.log as log
import supybot.world as world
@@ -61,10 +64,12 @@ def __init__(self):
self.schedule = []
self.events = {}
self.counter = 0
+ self.lock = Lock()
def reset(self):
- self.events.clear()
- self.schedule[:] = []
+ with self.lock:
+ self.events.clear()
+ self.schedule[:] = []
# We don't reset the counter here because if someone has held an id of
# one of the nuked events, we don't want him removing new events with
# his old id.
@@ -82,20 +87,22 @@ def addEvent(self, f, t, name=None, args=[], kwargs={}):
self.counter += 1
assert name not in self.events, \
'An event with the same name has already been scheduled.'
- self.events[name] = f
- heapq.heappush(self.schedule, mytuple((t, name, args, kwargs)))
+ with self.lock:
+ self.events[name] = f
+ heapq.heappush(self.schedule, mytuple((t, name, args, kwargs)))
return name
def removeEvent(self, name):
"""Removes the event with the given name from the schedule."""
f = self.events.pop(name)
- self.schedule = [x for x in self.schedule if f != name]
# We must heapify here because the heap property may not be preserved
# by the above list comprehension. We could, conceivably, just mark
# the elements of the heap as removed and ignore them when we heappop,
# but that would only save a constant factor (we're already linear for
# the listcomp) so I'm not worried about it right now.
- heapq.heapify(self.schedule)
+ with self.lock:
+ self.schedule = [x for x in self.schedule if f != name]
+ heapq.heapify(self.schedule)
return f
def rescheduleEvent(self, name, t):
@@ -123,8 +130,9 @@ def run(self):
'why do we continue to live?')
time.sleep(1) # We're the only driver; let's pause to think.
while self.schedule and self.schedule[0][0] < time.time():
- (t, name, args, kwargs) = heapq.heappop(self.schedule)
- f = self.events[name]
+ with self.lock:
+ (t, name, args, kwargs) = heapq.heappop(self.schedule)
+ f = self.events[name]
del self.events[name]
try:
f(*args, **kwargs)

0 comments on commit 9723e14

Please sign in to comment.