borgend/scheduler.py

changeset 104
d33e2d7dbeb1
parent 103
32f2154ef25e
child 106
a7bdc239ef62
equal deleted inserted replaced
103:32f2154ef25e 104:d33e2d7dbeb1
149 149
150 def _scheduler_thread(self): 150 def _scheduler_thread(self):
151 logger.debug("Scheduler thread started") 151 logger.debug("Scheduler thread started")
152 with self._cond: 152 with self._cond:
153 while not self._terminate: 153 while not self._terminate:
154 snapshot = dreamtime.Snapshot() 154 try:
155 now = snapshot.monotonic() 155 self.__schedule_one()
156 if not self._list: 156 except:
157 timeout = None 157 logger.exception("Bug in scheduler")
158 else: 158
159 delta = self._list.when.horizon(snapshot)-now 159 def __schedule_one(self):
160 if delta==math.inf: 160 snapshot = dreamtime.Snapshot()
161 timeout=None 161 now = snapshot.monotonic()
162 else: 162 if not self._list:
163 timeout = min(self.precision, delta) 163 timeout = None
164 164 delta = None
165 if not timeout or timeout>0: 165 nextname = None
166 logger.debug("Scheduler waiting %s seconds" % str(timeout)) 166 else:
167 self._cond.wait(timeout) 167 nextname=self._list.name
168 snapshot = dreamtime.Snapshot() 168 delta = self._list.when.horizon(snapshot)-now
169 now = snapshot.monotonic() 169 if delta==math.inf:
170 170 timeout=None
171 logger.debug("Scheduler timed out") 171 else:
172 172 timeout = min(self.precision, delta)
173 while self._list and self._list.when.horizon(snapshot) <= now: 173
174 ev=self._list 174 if not timeout or timeout>0:
175 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)")) 175 logger.debug("Scheduler waiting %s seconds [next event '%s' in %s seconds]"
176 # We are only allowed to remove ev from list when ev.cond allows 176 % (str(timeout), nextname, str(delta)))
177 self._unlink(ev) 177 self._cond.wait(timeout)
178 # We need to release the lock on self._cond before acquire 178 snapshot = dreamtime.Snapshot()
179 # one ev.cond to avoid race conditions with self._wait 179 now = snapshot.monotonic()
180 self._cond.release() 180 logger.debug("Scheduler timed out")
181 with ev.cond: 181
182 ev.cond.notify_all() 182 while self._list and self._list.when.horizon(snapshot) <= now:
183 self._cond.acquire() 183 ev=self._list
184 logger.debug("Scheduler activating %s" % (ev.name or "(unknown)"))
185 # We are only allowed to remove ev from list when ev.cond allows
186 self._unlink(ev)
187 # We need to release the lock on self._cond before acquire
188 # one ev.cond to avoid race conditions with self._wait
189 self._cond.release()
190 with ev.cond:
191 ev.cond.notify_all()
192 self._cond.acquire()
184 193
185 194
186 def _sleepwake_callback(self, woke): 195 def _sleepwake_callback(self, woke):
187 logger.debug("Rescheduling events after sleep/wakeup") 196 logger.debug("Rescheduling events after sleep/wakeup")
188 with self._cond: 197 with self._cond:
209 self._unlink(ev) 218 self._unlink(ev)
210 #ev.cond.acquire() 219 #ev.cond.acquire()
211 220
212 # cond has to be acquired on entry! 221 # cond has to be acquired on entry!
213 def wait_until(self, when, cond, name=None): 222 def wait_until(self, when, cond, name=None):
214 logger.debug("Scheduling '%s' in %s seconds [%s]" % 223 logger.info("Scheduling '%s' in %0.01f seconds / on %s [%s]" %
215 (name, when.seconds_to(), when.__class__.__name__)) 224 (name, when.seconds_to(), when.isoformat(),
225 when.__class__.__name__))
216 self._wait(ScheduledEvent(when, cond, name)) 226 self._wait(ScheduledEvent(when, cond, name))
217 227

mercurial