Skip to content

Instantly share code, notes, and snippets.

@wickman
Created October 5, 2012 16:24
Show Gist options
  • Save wickman/3840816 to your computer and use it in GitHub Desktop.
Save wickman/3840816 to your computer and use it in GitHub Desktop.

Revisions

  1. wickman created this gist Oct 5, 2012.
    71 changes: 71 additions & 0 deletions clock.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    from abc import ABCMeta, abstractmethod
    import threading


    class ClockInterface(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def time(self):
    pass

    @abstractmethod
    def tick(self, amount):
    pass

    @abstractmethod
    def sleep(self, amount):
    pass


    class Handshake(object):
    def __init__(self):
    self._syn_event = threading.Event()
    self._ack_event = threading.Event()

    def syn(self):
    self._syn_event.wait()
    self._ack_event.set()

    def ack(self):
    self._syn_event.set()
    self._ack_event.wait()


    class ThreadedClock(ClockInterface):
    def __init__(self):
    self._time = 0
    self._waiters = [] # queue of [stop time, Handshake]

    def time(self):
    return self._time

    def _pop_waiter(self, end):
    times_up = sorted((waiter for waiter in self._waiters if waiter[0] <= end),
    key=lambda element: element[0])
    if times_up:
    waiter = times_up[0]
    self._waiters.remove(waiter)
    return waiter

    def tick(self, amount):
    now = self._time
    end = now + amount

    while True:
    waiter = self._pop_waiter(end)
    if not waiter:
    break

    waiter_time, waiter_handshake = waiter
    self._time = waiter_time
    waiter_handshake.ack()

    self._time = end

    def sleep(self, amount):
    waiter_end = self._time + amount
    waiter_handshake = Handshake()

    self._waiters.append((waiter_end, waiter_handshake))
    waiter_handshake.syn()