| Loic Domaigne 2005-07-26, 5:57 pm |
| Hi Rafal,
[snip]
> Now these threads are communicating with the printer. It is necessary for them
> to timeout when reading and writing to the device lasts to long. So I am
> installing handler for SIGALRM using sigaction with sa_flags = SA_INTERRUPT, I
> call alarm(time) just before read() or write() to the device and... after
> receiving SIGALRM by the process only accept() call in main thread is
> interrupted.
> What am I doing wrong?
The problem you are faced is due to the POSIX semantic for signal
delivery in a multi-threaded process. The SIGALRM might be delivered to
any thread in the process, not necessarily the one that called alarm().
> How can I interrupt read() call?
Assuming that the read() you want to interrupt is called from a single
thread, block SIGALRM in all but that thread using pthread_sigmask().
> Everything works as I expected when there is only one thread - I've tried to
> remove networking and threads stuff from the application and only call the
> function responsible for communication with the printer - then read() call got
> interrupted.
> I am using glibc 2.3.2 and gcc 3.3.5 (Debian 1:3.3.5-13).
Yes, since it there's only an unique thread where the signal can be
delivered.
You are probably using NPTL. Alternatively, you could switch back to
LinuxThreads to get your program working. Indeed, with LinuxThreads
SIGALRM is always delivered to the thread calling alarm(). But you can't
rely on this property for portable programs.
Cheers,
Loic.
|