Re: HR timers prevent an itimer from generating EINTR?

From: Roland McGrath
Date: Fri Sep 25 2009 - 04:16:18 EST


Oleg is correct. As he's explained, what we expect to be likely in your
scenario is that the SA_RESTART signal has already "prevented the syscall
from happening" by rolling it back at the time the non-SA_RESTART signal
happens, so there is no syscall to get EINTR. Then it goes ahead and
starts the syscall, after both signals have come and gone.

It's really the same case as if you'd suspended the program with ^Z between
setting the timer and making the flock call and then resumed it more than
three seconds later. Or just an obscenely long scheduling delay from
higher priority tasks. Or if you'd been stepping it in the debugger and
took that long to hit return that many times. Or if that printf/fflush had
blocked in write because the pipe/pty/socket buffers were all full along
the path to your terminal and it took three seconds for the network to
unclog, or whatever it was.

It's true that you can observe the difference between those cases and the
syscall restart case, if e.g. the syscall clearly had begun to happen
because you'd already blocked for most of a second and could tell that was
so somehow. But that thread itself can't really tell, and you don't get
any guarantee that because you somehow externally think the syscall had
been started, your thread won't semantically be said to be in user mode
sitting at the syscall instruction but not having executed it yet. So
indeed that's what we'll say when after that the SA_RESTART signal hits.

You really can't get the kind of guaranteed-raceless interruption you are
expecting using signals with arbitrary calls in POSIX. Only with a few
that specifically take a blocked signal set to install inside the syscall
before they block, like ppoll/pselect. You may be looking for the model
that pthread_cancel gives you (unfortunately it requires you to use a
separate thread and to have it entirely cancelled to effect an interrupt).
fcntl (flock) is a cancellation point, meaning a prior pthread_cancel has
the "sticky" effect you want even in "deferred cancel" mode.


Thanks,
Roland

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/