help with starting python thread in dbus call



Basically I have a python dbus server that needs to start a thread when a method is called. Like so:

@dbus.service.method(dbus_interface='EncodingServer.Interface', in_signature='', out_signature='')
   def start_encoding(self):
# Here we start the encoder thread then return. The thread should continue after we return, but it freezes. encoder = EncoderThread() # this is a thread like: EncoderThread(threading.Thread)
       encoder.start()

It looks like this is an issue with the gobject mainloop blocking the python thread execution. I have found many posts talking about this, but no solution. Also note that the encoder thread could run for hours, so calling the method asynchronously on the client will time out, and is not really desired.

I've attached an example client and server to better explain my point. Notice that if you kill the server's main loop with control+c, the gobject main loop dies and the thread continues as normal.

Any help would be appreciated! Also, I'm new to dbus, so I may have a stupid design here.
import dbus, dbus.glib, gobject

def start_program():
    bus = dbus.SessionBus()
    server = dbus.Interface(bus.get_object('EncodingServer.Server', '/'),
                        'EncodingServer.Interface')
    server.start_encoding()
    print "client started server encoding."
    return False

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
gobject.timeout_add(1000, start_program)

loop = gobject.MainLoop()
loop.run()

print "client done!"

import dbus, dbus.glib, dbus.service
import gobject, os, time, threading

class EncoderThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            print "encoding ..."
            time.sleep(1)

class EncodingServer(dbus.service.Object):
    def __init__(self, a, b):
        super(EncodingServer, self).__init__(a, b)

    @dbus.service.method(dbus_interface='EncodingServer.Interface', in_signature='', out_signature='')
    def start_encoding(self):
        # Here we start the encoder thread then return. The thread stops when we return, instead of continuing.
        encoder = EncoderThread()
        encoder.start()

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

# Advertise the Encoding server
session_bus = dbus.SessionBus()
name = dbus.service.BusName('EncodingServer.Server', bus=session_bus)
obj = EncodingServer(name, '/')

print 'EncodingServer Listening'
loop = gobject.MainLoop()
loop.run()




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]