I try to stop a gobject.MainLoop()
after a few seconds.
I don't know if it's possible to set a timeout to this kind of loop, it would be perfect but I have not found that.
So, I tried to workaround this with threading but unfortunately, the main loop block others threads.
Here my code (I'm working with python 2.7):
import MediaCenter_dbusConfig
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
from time import sleep
from threading import Thread
mainloop=0
class Timeout(Thread):
global mainloop
def __init__(self):
Thread.__init__(self)
def run(self):
global mainloop
i = 0
while i < 30:
sleep(1)
i += 1
mainloop.quit()
class Loop(Thread):
global mainloop
def __init__(self):
Thread.__init__(self)
def run(self):
global mainloop
sleep(5)
mainloop.run()
def catchall_detectedDevicePopUp_from_willShowPopup_signals_handler(popup_string):
global mainloop
if(popup_string == "DetectedDevicePopUp.qml") :
print(popup_string)
mainloop.quit()
def detectedDevicePopUp_detector() :
global mainloop
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus=MediaCenter_dbusConfig.init() # basicly do a dbus.bus.BusConnection()
bus.add_signal_receiver(catchall_detectedDevicePopUp_from_willShowPopup_signals_handler, dbus_interface = "com.orange.mediacenter.apimanager", signal_name = "willShowPopup")
mainloop = gobject.MainLoop()
thread1 = Timeout()
thread2 = Loop()
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Here I call detectedDevicePopUp_detector()
. I'm waiting for a signal named willShowPopup
. If I received a signal, I want to stop the loop and continue my program, and after 30s, if I have not received any signal, I want the same thing (stop the loop and continue my program) but here it doesn't work, my Timeout
thread is blocked by my Loop
thread.
Clarification: I can not edit the signals sent (I test an application).
Any ideas ?
As I understood the question, threading is not really wanted. Below is an example that uses gobject.timeout_add
to add a maximum time that the mainloop will run if there is no signal to stop it:
import gobject
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
OPATH = "/com/example/StopLoop"
IFACE = "com.example.StopLoop"
BUS_NAME = "com.example.StopLoop"
TIMEOUT = 30 * 1000
class Example(dbus.service.Object):
def __init__(self, loop):
self.loop = loop
bus = dbus.SessionBus()
bus.request_name(BUS_NAME)
bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
dbus.service.Object.__init__(self, bus_name, OPATH)
# Add a timeout for how long to run mainloop
# if no signal is received
self.setup_timeout(TIMEOUT)
# Listen to the "Stop" signal
self.listen_for_signal(bus)
def setup_timeout(self, timeout):
gobject.timeout_add(timeout, self.handler)
def listen_for_signal(self, bus):
bus.add_signal_receiver(self.handler, "Stop")
def handler(self):
# This handler is used for both timeout and signal
self.loop.quit()
if __name__ == "__main__":
loop = gobject.MainLoop()
a = Example(loop)
loop.run()
print "Exited mainloop, continuing program..."
If the Stop
signal is received e.g. by doing:
dbus-send --session --type=signal --dest=com.example.StopLoop /com/example/StopLoop com.example.StopLoop.Stop
The mainloop will exit and the code will continue from where loop.run()
was called.
If no signal is received the mainloop will be stopped by the timeout (30 seconds in this case) and continue from where loop.run()
was called.