Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> writes:
> On 19/08/10 20:18, Tom Lane wrote:
>> But I'm still not seeing how this self-pipe hack avoids a race
>> condition. If the signal handler is sending a byte whenever it
>> executes, then you could have bytes already stacked up in the pipe
>> from previous interrupts that didn't happen to come while inside
>> pg_usleep. If you clear those before sleeping, you have a race
>> condition, and if you don't, then you fail to sleep the intended
>> amount of time even though there was no interrupt this time.
> You clear the pipe after waking up.
Hmm ... that doesn't answer my second objection about failing to sleep
the expected amount of time, but on reflection I guess that can't be
done: we have to be able to cope with interrupts occurring just before
the sleep actually begins, and there's no way to define "just before"
except by reference to the calling code having done whatever it might
need to do before/after sleeping.
> Hmm, will need to think about a suitable API for that.
Offhand I'd suggest something like
SetSleepInterrupt() -- called by signal handlers, writes pipe
ClearSleepInterrupt() -- called by sleep-and-do-something loops, clears pipe
pg_usleep() itself remains the same, but it is now guaranteed to return
immediately if SetSleepInterrupt is called, or has been called since the
last ClearSleepInterrupt.
> The nice thing
> would be that we could implement it using pselect() where available.
> (And reliable - the Linux select() man page says that glibc's pselect()
> is emulated using select(), and suffers from the very same race
> condition pselect() was invented to solve. How awful is that!?)
Ick. So how would you tell if it's trustworthy?
regards, tom lane