On Tuesday 28 June 2005 04:15, Mario Sergio Fujikawa Ferreira wrote:
[snip]
I added a few fprintf(stderr, ) traces to glibmm dispatch.cc
code so that I could pin point exactly where the problem occured. It
seems to me that it is a problem with reentrancy since nothing
guarantees that the write(2) call on the sender is atomic.
Which is reinforced by the comment right below the write(2)
call on the DispatchNotifier::send_notification() method on
http://cvs.gnome.org/viewcvs/glibmm/glib/glibmm/dispatcher.cc?rev=1.12view
=markup
// All data must be written in a single call to write(), otherwise we
can't
// guarantee reentrancy since another thread might be scheduled between
two
// write() calls. The manpage is a bit unclear about this -- but I hope
// it's safe to assume immediate success for the tiny amount of data
we're
// writing.
Well, I am hitting a wall here. Glib::Dispatcher is not
reentrant and there is little I can do about it.
Adding per Dispatcher mutex protections around the write(2) system call
do-while loop
while (sender_mutex_.trylock() == false)
Glib::Thread::yield();
do
n_written = write(fd_sender_, data, sizeof(data));
while(n_written 0 errno == EINTR);
sender_mutex_.unlock();
does not protect against lockups. Nor does adding a mutex inside
Dispatcher::emit().
void Dispatcher::emit()
{
Glib::Mutex::Lock lock_(mutex);
notifier_-send_notification(this);
}
Checking the mailing lists, I found some interesting remarks
http://mail.gnome.org/archives/gtkmm-list/2002-September/msg0.html
which do point out the reentrancy problem.
There is a suggested solution at
http://mail.gnome.org/archives/gtkmm-list/2002-September/msg8.html
pointing out that a lock-free FIFO multiple-writers-single-reader could
be the solution. I do agree that this is non trivial.
The POSIX Single Unix Specification provides in relation to write() that:
Write requests to a pipe or FIFO shall be handled in the same way as a
regular file with the following exceptions:
...
Write requests of {PIPE_BUF} bytes or less shall not be interleaved with
data from other processes doing writes on the same pipe. Writes of greater
than {PIPE_BUF} bytes may have data interleaved, on arbitrary boundaries,
with writes by other processes, whether or not the O_NONBLOCK flag of the
file status flags is set.
...
PIPE_BUF is never less than 512 and is usually 2048 in size. Admittedly the
standard only requires writes by different processes to be atomic with a
write of a size not greater than that, but it would be odd if the same
behaviour were not exhibited by different threads within one process. If you
are using Windows, I thought that it was POSIX compliant?
Unfortunaly gnome.org is down at the moment so I cannot look up your mailing
list references, but why is it that mutexes around the write call don't solve
the issue (if in fact different threads within the same process do not
benefit from the POSIX atomicity guarantees)? That should avoid concurrent
writes to the Dispatcher pipe in every case.
Chris
___
gtkmm-list mailing list
gtkmm-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtkmm-list