daemon: Simplify event loop timer processing.

This commit is contained in:
Tom Goff 2015-11-05 12:36:44 -05:00
parent c8d5ec994a
commit 28c27d27c1

View file

@ -16,8 +16,8 @@ class EventLoop(object):
class Timer(threading.Thread): class Timer(threading.Thread):
'''\ '''\
Based on threading.Timer with additional support to tell if Based on threading.Timer but cancel() returns if the timer was
the timer is currently running its callback. already running.
''' '''
def __init__(self, interval, function, args=[], kwargs={}): def __init__(self, interval, function, args=[], kwargs={}):
@ -27,31 +27,25 @@ class EventLoop(object):
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
self.finished = threading.Event() self.finished = threading.Event()
self._running = False self._running = threading.Lock()
self._running_lock = threading.Lock()
def is_running(self):
with self._running_lock:
running = self._running
return running
def _set_running(self, val):
with self._running_lock:
running = self._running
self._running = val
return running
def cancel(self): def cancel(self):
"""Stop the timer if it hasn't finished yet""" '''\
self.finished.set() Stop the timer if it hasn't finished yet. Return False if
the timer was already running.
'''
locked = self._running.acquire(False)
if locked:
self.finished.set()
self._running.release()
return locked
def run(self): def run(self):
self.finished.wait(self.interval) self.finished.wait(self.interval)
if not self.finished.is_set(): with self._running:
self._set_running(True) if not self.finished.is_set():
self.function(*self.args, **self.kwargs) self.function(*self.args, **self.kwargs)
self._set_running(False) self.finished.set()
self.finished.set()
class Event(object): class Event(object):
def __init__(self, eventnum, time, func, *args, **kwds): def __init__(self, eventnum, time, func, *args, **kwds):
@ -155,10 +149,8 @@ class EventLoop(object):
heapq.heappush(self.queue, event) heapq.heappush(self.queue, event)
head = self.queue[0] head = self.queue[0]
if prevhead is not None and prevhead != head: if prevhead is not None and prevhead != head:
if self.timer is not None and not self.timer.is_running(): if self.timer is not None and self.timer.cancel():
self.timer.cancel()
self.timer = None self.timer = None
if self.running and self.timer is None: if self.running and self.timer is None:
self.__schedule_event() self.__schedule_event()
return event return event