| 152 def _scheduler_thread(self): |
152 def _scheduler_thread(self): |
| 153 logger.debug("Scheduler thread started") |
153 logger.debug("Scheduler thread started") |
| 154 with self._cond: |
154 with self._cond: |
| 155 while not self._terminate: |
155 while not self._terminate: |
| 156 snapshot = dreamtime.Snapshot() |
156 snapshot = dreamtime.Snapshot() |
| 157 now = snapshot.monotonic() |
|
| 158 if not self._list: |
157 if not self._list: |
| 159 timeout = None |
158 timeout = None |
| 160 delta = None |
159 delta = math.inf |
| 161 nextname = None |
160 nextname = None |
| 162 else: |
161 else: |
| 163 nextname=self._list.name |
162 nextname=self._list.name |
| 164 delta = self._list.when.horizon(snapshot)-now |
163 delta = self._list.when.horizon(snapshot) |
| 165 if delta==math.inf: |
164 if delta==math.inf: |
| 166 timeout=None |
165 timeout=None |
| 167 else: |
166 else: |
| 168 timeout = min(self.precision, delta) |
167 timeout = min(self.precision, delta) |
| 169 |
168 |
| 170 if not timeout or timeout>0: |
169 if not timeout or timeout>0: |
| 171 logger.debug("Scheduler waiting %s seconds [next event '%s' in %s seconds]" |
170 logger.debug("Scheduler waiting %s seconds [next event '%s' in %0.2f seconds]" |
| 172 % (str(timeout), nextname, str(delta))) |
171 % (str(timeout), nextname, delta)) |
| 173 self._cond.wait(timeout) |
172 self._cond.wait(timeout) |
| 174 snapshot = dreamtime.Snapshot() |
173 snapshot = dreamtime.Snapshot() |
| 175 now = snapshot.monotonic() |
|
| 176 logger.debug("Scheduler timed out") |
174 logger.debug("Scheduler timed out") |
| 177 |
175 |
| 178 while self._list and self._list.when.horizon(snapshot) <= now: |
176 while self._list and self._list.when.horizon(snapshot) <= 0: |
| 179 ev=self._list |
177 ev=self._list |
| 180 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)")) |
178 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)")) |
| 181 # We are only allowed to remove ev from list when ev.cond allows |
179 # We are only allowed to remove ev from list when ev.cond allows |
| 182 self._unlink(ev) |
180 self._unlink(ev) |
| 183 # We need to release the lock on self._cond before acquire |
181 # We need to release the lock on self._cond before acquire |
| 215 #ev.cond.acquire() |
213 #ev.cond.acquire() |
| 216 |
214 |
| 217 # cond has to be acquired on entry! |
215 # cond has to be acquired on entry! |
| 218 def wait_until(self, when, cond, name=None): |
216 def wait_until(self, when, cond, name=None): |
| 219 logger.info("Scheduling '%s' in %0.01f seconds / on %s [%s]" % |
217 logger.info("Scheduling '%s' in %0.01f seconds / on %s [%s]" % |
| 220 (name, when.seconds_to(), when.isoformat(), |
218 (name, when.remaining(), when.isoformat(), |
| 221 when.__class__.__name__)) |
219 when.__class__.__name__)) |
| 222 self._wait(ScheduledEvent(when, cond, name)) |
220 self._wait(ScheduledEvent(when, cond, name)) |
| 223 |
221 |