71 self.daemon = True |
71 self.daemon = True |
72 self._list = None |
72 self._list = None |
73 |
73 |
74 def _insert(self, ev): |
74 def _insert(self, ev): |
75 if not self._list: |
75 if not self._list: |
|
76 #logger.debug("Insert first") |
76 self._list=ev |
77 self._list=ev |
77 elif ev<self._list: |
78 elif ev<self._list: |
|
79 #logger.debug("Insert beginning") |
78 self._list.insert_immediately_before(ev) |
80 self._list.insert_immediately_before(ev) |
79 self._list=ev |
81 self._list=ev |
80 else: |
82 else: |
|
83 #logger.debug("Insert after") |
81 self._list.insert_after(ev) |
84 self._list.insert_after(ev) |
82 |
85 |
83 self._cond.notify() |
86 self._cond.notify() |
84 |
87 |
85 def _unlink(self, ev): |
88 def _unlink(self, ev): |
96 self.precision = precision |
99 self.precision = precision |
97 self._next_event_time = None |
100 self._next_event_time = None |
98 super().__init__(target = self._scheduler_thread, name = 'Scheduler') |
101 super().__init__(target = self._scheduler_thread, name = 'Scheduler') |
99 |
102 |
100 def _scheduler_thread(self): |
103 def _scheduler_thread(self): |
|
104 logger.debug("Scheduler thread started") |
101 with self._cond: |
105 with self._cond: |
102 while not self._terminate: |
106 while not self._terminate: |
103 now = time.monotonic() |
107 now = time.monotonic() |
104 if not self._list: |
108 if not self._list: |
105 timeout = None |
109 timeout = None |
107 # Wait at most precision seconds, or until next event if it |
111 # Wait at most precision seconds, or until next event if it |
108 # comes earlier |
112 # comes earlier |
109 timeout=min(self.precision, self._list.when-now) |
113 timeout=min(self.precision, self._list.when-now) |
110 |
114 |
111 if not timeout or timeout>0: |
115 if not timeout or timeout>0: |
|
116 logger.debug("Scheduler waiting %d seconds" % (timeout or (-1))) |
112 self._cond.wait(timeout) |
117 self._cond.wait(timeout) |
113 now = time.monotonic() |
118 now = time.monotonic() |
|
119 |
|
120 logger.debug("Scheduler timed out") |
114 |
121 |
115 while self._list and self._list.when <= now: |
122 while self._list and self._list.when <= now: |
116 ev=self._list |
123 ev=self._list |
117 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)")) |
124 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)")) |
118 # We are only allowed to remove ev from list when ev.cond allows |
125 # We are only allowed to remove ev from list when ev.cond allows |
134 with self._cond: |
141 with self._cond: |
135 self._unlink(ev) |
142 self._unlink(ev) |
136 |
143 |
137 # cond has to be acquired on entry! |
144 # cond has to be acquired on entry! |
138 def wait_until(self, when, cond, name=None): |
145 def wait_until(self, when, cond, name=None): |
|
146 logger.debug("Scheduling '%s' at %d" % (name, when)) |
139 self._wait(ScheduledEvent(when, cond, name)) |
147 self._wait(ScheduledEvent(when, cond, name)) |
140 |
148 |