Re: [sigc] Re: [gtkmm] libsigcx and gtkmm 2.4



Am 13.06.2004 00:03:36 schrieb(en) Daniel Elstner:
Am Sa, den 12.06.2004 um 15:19 Uhr +0200 schrieb Christer Palm:

> Thanks Martin!
>
> I "stole" the basic principles from your class to create my own
variant
> of a multi-argument Gtk::Dispatcher. As I think this is some pretty
> useful stuff, I'm posting the result here.
>
> Perhaps this could be adapted to go into the Glibmm distribution?
> Let me all know what you think.

The problem is that I'm still not convinced that cross-thread
signalling
with arguments can be implemented correctly as a generic template.
From
Martin's description of the SigCX solution it appears that a so- called
synchronous mode is used to get around that:

The synchronous mode can optionally be used if the execution of the calling thread should be suspended until the dispatcher has handled the signal. It is not intended to be used as a work-around; asynchronous mode should always work.


      disp.tunnel(sigc::bind(&foo, std::string("hello world")));
      /*
         - call this function from any thread;
         - bind up to 7 arguments at once
         - pass 'true' as a second argument if the slot should
           be executed synchronously;
         - make use of signal::make_slot() if the dispatcher
           should emit a signal;
       */

Hmm std::string is a perfect example of an argument type that requires
special handling.

Why? The slot object is completely initialized before the dispatcher knows of it. Note that sigc::bind does not take arguments as references by default if this is where you are heading.

So assuming "synchronously" does what I think it
does, why doesn't the example use this mode?

How does this synchronous thing work?  Does it really wait for the
main
loop to process the signal, and wouldn't that defeat the purpose of
threads?

Yes it does, and well, I have no use the synchronous mode currently.

 Even if it does this you still need mutex locking to protect
the memory being shared (ensuring that event A happens after event B
is
not enough due to the way modern hardware works; you definitely need
memory barriers too).

Why would you need memory barries? Thread A creates some objects, thread B (the dispatcher) uses them and destroys them afterwards. Of course, if you pass references around, you need to make sure that thread A doesn't manipulate the data while thread B is handling it, yourself.

Regards,

 Martin




Also, you can always use plain Glib::Dispatcher in conjunction with a
Glib::Mutex to pass data around.  This way you're forced to think
about
the locking which is IMHO a good thing.

When I thought about adding signal parameter support to
Glib::Dispatcher
a while ago, I played with the idea of making Glib::Dispatcher provide
a
low-level interface for sending raw blocks of memory through the pipe.
On top of that there could be some kind of plugin interface that
requires you to implement two functions that convert your data to raw
memory and back again.  I don't think it should be entirely automagic
through templates since that'd give the user a false sense of
security.
The big advantage of course is avoidance of any locking whatsoever.

Comments, corrections, insights, etc. will be appreciated.

Cheers,
--Daniel






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