class Executor: def __init__(self): self.lock = Lock() self.cond = Condition(self.lock) self.wg = None # TODO sync.WaitGroup self.finished = False self.events = [] def Initialize(self): self.wg.Add(1) def Add(self, event): self.lock.Lock() # TODO defer self.lock.Unlock() self.events = append(self.events, event) self.cond.Signal() def Stop(self): self.lock.Lock() if not self.finished: # TODO defer self.wg.Wait() pass # TODO defer self.lock.Unlock() self.finished = true self.cond.Broadcast() def Dispatch(self): self.lock.Lock() # TODO defer self.lock.Unlock() # TODO defer self.wg.Done() while not self.finished: if len(self.events) == 0: self.cond.Wait() else: event = self.events[0] self.events = self.events[1:] self.lock.Unlock() event() self.lock.Lock()
class DBusObject(dbus.service.Object): def __init__(self, busname, servicename, bus): self._busname = busname self._servicename = servicename self._bus = bus self._signals_caught = {} self._siglock = Lock() def _startup(self): pass def _shutdown(self): pass def _exception(self, e): syslog.syslog("DBusObject exception: %s" % e) def run(self): DBusGMainLoop(set_as_default=True) bus_name = dbus.service.BusName(self._busname, self._bus) dbus.service.Object.__init__(self, bus_name, self._servicename) self._startup() try: self._loop = gobject.MainLoop() self._loop.run() except Exception as e: self._exception(e) # Release all signals remaining for signame in sself._signals_caught: self.uncatch_signal(signame) self._shutdown() def catch_signal(self, signame, action): self._siglock.Lock() if not callable(action): raise DboException("action is not callable for signal %s", signame) # Remove signal if currently being caught if signame in self._signals_caught: self.uncatch_signal(signame) self._signals_caught[signame] = { 'signame': signame, 'action': action, 'receiver': self._bus.add_signal_receiver(action, dbus_interface=self._busname, signal_name=signame) } self._sigLock.Unlock() def uncatch_signal(self, signame): self._siglock.Lock() if signame in self._signals_caught: self._bus.remove_signal_receiver( self._signals_caught[signame]['action'], self._signals_caught['receiver'], dbus_interface=self._busname) self._siglock.Unlock()