Glib::Dispatcher (multiple emit/write lockup)
- From: Mario Sergio Fujikawa Ferreira <lioux-list uol com br>
- To: gtkmm-list gnome org
- Subject: Glib::Dispatcher (multiple emit/write lockup)
- Date: Tue, 28 Jun 2005 03:15:03 +0000
Hi,
I have an application running multiple threads and making heavy
use of dispatchers. The application seemed to lock up erractically.
$ kill -11 app_id
$ gdb app core
Doing some gdb back tracing, it all traced back to dispatch emit() then
to the write(2) system call.
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.12&view=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/msg00000.html
which do point out the reentrancy problem.
There is a suggested solution at
http://mail.gnome.org/archives/gtkmm-list/2002-September/msg00008.html
pointing out that a lock-free FIFO multiple-writers-single-reader could
be the solution. I do agree that this is non trivial.
Has anyone worked on such a solution? I did a very ugly work
around in the mean time.
void Dispatcher::emit()
{
Glib::usleep(1000);
notifier_->send_notification(this);
}
I'll probably add a rand addition to that to avoid timed
collisions. However, this is an undesirable at best. :)
Any takers?
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]