Re: Glib::Dispatcher1<T>



Am Samstag, den 20.01.2007, 12:22 +0000 schrieb Chris Vine:

> It will be necessary to provide synchronisation of course - Glib::SignalIdle 
> does this through attaching to the glib main loop, whereas Glib::Dispatcher 
> is only attached once and thereafter can be invoked from time to time with 
> (under your proposal) different arguments.  I would tend to use a semaphore 
> in this use (after writing the argument the signalling thread calls 
> sem_post(), a release, and before reading the argument the main loop 
> dispatching thread calls sem_wait(), an acquire), but glib doesn't have them.

I don't get it.  Why should there be a need for any synchronization
beyond the memory barrier when passing pointers to custom types?  Note
that I'm proposing to stream the data argument through the pipe.  Some
pseudo code:

send_notification(...)
{
   DispatchNotifyData data (dispatcher, this, arg_union);

   if (is_dynamic)
     // Lock and immediately unlock mutex to issue a memory barrier.
     Glib::Mutex::Lock lock (mutex_);

   write(fd, &data, sizeof(data));
   ...
}

receive_notification(...)
{
   DispatchNotifyData data;

   read(fd, &data, sizeof(data));

   if (is_dynamic)
     // Sync with memory barrier in send_notification().
     Glib::Mutex::Lock lock (mutex_);

   data.dispatcher->emit_signal(data.arg_union);
   ...
}

> Are you going to put a mutex around the argument in the sending and receiving 
> thread?

Only for the pointer specializations (and not really *around* the
read/write, I got that wrong in my proposal mail).  And even for pointer
types this will be only the default behavior.  If you know what you're
doing (e.g. when passing a pointer to static data), you may disable the
extra lock/unlock.

> What I tend to do for passing arguments to dispatcher-type invocations is use 
> a std::queue object with mutex locking of the queue.  That would also be a 
> means of implementing your templated Dispatcher proposal and would not be 
> restricted to built-in types.

Well since builtin types also include typed pointers the restriction is
not that severe.  The only catch is that you have to handle the memory
management yourself.  But the interface should be well suited for
implementing such a queue on top of it.

I really want to avoid any implicit memory allocation if I can help it,
since memory allocation means locking unless you implement your own
allocator.  The idea is that emission is as cheap as it can possibly be,
so that the number-cruncher thread or whatever can just keep running.
And if you need it, you can always implement a high-level interface on
top of the low-level one, whereas it would be rather difficult the other
way around.

Cheers,
--Daniel





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