Re: gtkmm-list Digest, Vol 14, Issue 43
- From: Mario Sergio Fujikawa Ferreira <lioux-list uol com br>
- To: gtkmm-list gnome org
- Cc: Chris Vine <chris cvine freeserve co uk>
- Subject: Re: gtkmm-list Digest, Vol 14, Issue 43
- Date: Fri, 01 Jul 2005 10:38:23 +0000
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?
That does not protect against race conditions. If the
send_notification (emit()) thread is interrupted right in the middle of
the write(2) call, we will end up with another thread doing a write(2)
and another one overlapping is atomicity is not guaranteed. As per the
POSIX standard upholding, I am not seeing such atomicity guarantees
under Conectiva Linux 9 kernel 2.4.x series with Linuxthreads. It could
be just a problem with my development environment (which should not be
since I am able to reproduce this problem under Mandriva Linux) but we
should not rely on that but do take a safer approach right from the
start.
Also, not all systems are fully POSIX compliant and the libs
should (I emphasize should over "have to" here :) do their best to
produce similar behavior despite the environment differences.
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.
Okay, here is my theory from what I gathered from gdb. This is
just a theory. Others more experienced with {glib,gtk}mm inner workings
should know better. Well, under some irregular circunstances it is
possible to lock up all threads (including the main thread and the
controller thread for that matter) if a send_notification thread is
preempted in the middle of it's execution while holding the lock. If
the main/controller thread tries to use the send_notification (emit()),
it will end up waiting on that mutex. Dead lock. Any way, even if this
is not the case, I am experienced deadlocks with that approach.
Well, it could be said that I have a flawed program design.
However, we are doing it all by the book, mutexes on the dispatcher
method receiver, etc. And, the program runs smoothly with the sleep
trick.
void Dispatcher::emit()
{
Glib::usleep(1000);
notifier_->send_notification(this);
}
--
Mario
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]