[omniORB] Integration into a foreign event-loop
Felix Nawothnig
fn at drdannenberg.de
Wed Jul 22 21:15:26 BST 2009
Duncan Grisby wrote:
>> Now, as most widget toolkits Qt needs all GUI related calls be done in a
>> single thread (actually Qt even needs that thread to be the original
>> main() thread).
> Does it really? I don't know anything much about Qt, but a quick search
> around finds lots of information about multi-threaded programming with
> Qt.
Yes it does. :-) Although Qt supports multi-threading (and provides a
rather cool concurrency framework) all the widgets are not thread-safe,
and QApplication::exec() must be called from inside the main() thread
(you'll get an assertion failure otherwise).
I suppose this is for performance reasons - same reason Microsoft
decided against coming up with a thread-safe GUI for .NET.
Of course there's a simple way to do multi-threading with Qt - signals
and slots. Similar to .NET where you have to use BeginInvoke to marshal
data into the main thread in Qt you use signals and slots - QObjects are
thread-aware and know in which thread they were created, signaling
checks the received thread and marshals the call into the event-loop if
the threads differ (by default same-thread emits result in just a
function call).
When you're using signals and slots as your inter-process communication
mechanism (which is possible with QtDBus) everything's fine and straight
forward - but an ORB doesn't emit Qt signals, it calls servant methods. :-)
So you have to invent a signal (from the servant) and a slot (into a
dummy object) for each incoming invocation and connect them - this leads
to massive amount of boilerplate code I'd like to avoid.
> omniORB doesn't have an event loop per se. It always has multiple
> threads handling incoming calls and connection attempts. The main thread
> POA policy is implemented using thread switching between the thread that
> would normally have handled an upcall into the main thread. It is
> therefore a lot less efficient than the normal threading policies.
Yea, I realized that after digging through the code some more.
Efficiency wouldn't be much of an issue in this case, after all it's
about data coming in modifying a GUI.
> Rather than the wait_for_work function you propose, I think a better
> idea is to allow the application to register a function that is called
> whenever a main thread task is inserted. i.e. at the point the code
> currently does invoker_signal.signal(), it could call an
> application-provided function. In your case, that function would send a
> signal to the Qt main thread, instructing it to call perform_work.
Agreed.
> If you send a clean patch that implements that scheme, I will definitely
> consider integrating it in omniORB.
Alright, I'll give it a try.
Cheers,
Felix
More information about the omniORB-list
mailing list