udevd move from select() to ppoll()
Hi,
I'm writing as I recently encountered a regression after the select() --> ppoll() move in the udevd daemon, running on uClibc-0.9.29 and at least kernels since 2.6.28.
For some reason the ppoll call always returns -1 w/ EINVAL in this configuration. I actually anticipate this to be a bug in either Linux or uClibc...
However, while investigating this, I came across the following sequence of steps performed in udevd.c (line 973):
fdcount = ppoll(pfd, nfds, NULL, &orig_mask);sigprocmask(SIG_SETMASK, &orig_mask, NULL);
Maybe I am missing something, but my reading of the man page indicates that the following sequence would accomplish the same work, but would be faster, as it eliminates the restoration of blocked_mask at the end of the ppoll() call, which then proceeds to be overwritten again to what it was inside ppoll by the above sigprocmask() call.
Would it be basically the same to do the following (but faster)?
sigprocmask(SIG_SETMASK, &orig_mask, NULL);
fdcount = poll(pfd, nfds, -1);
Additionally, this reportedly fixes the EINVAL that is hit in uClibc too, which doesn't reach the error condition in poll().
Signature · 1 line
Coleman Kane
Quoted 3 lines · Coleman Kane
For some reason the ppoll call always returns -1 w/ EINVAL in this configuration. I actually anticipate this to be a bug in either Linux or uClibc...
Likely the libc, I did not hear of any such problems somewhere else. What does strace show?
Quoted 12 lines
However, while investigating this, I came across the following sequence of steps performed in
udevd.c(line 973):fdcount =
ppoll(pfd, nfds, NULL, &orig_mask);sigprocmask(SIG_SETMASK, &orig_mask, NULL);Maybe I am missing something, but my reading of the man page indicates that the following sequence would accomplish the same work, but would be faster, as it eliminates the restoration of
blocked_maskat the end of theppoll()call, which then proceeds to be overwritten again to what it was inside ppoll by the abovesigprocmask()call.
Quoted 4 lines
Would it be basically the same to do the following (but faster)?
sigprocmask(SIG_SETMASK, &orig_mask, NULL);
fdcount =poll(pfd, nfds, -1);
If signals happen between this sigprocmask() and the poll(), you go to sleep, even when you need to do work. The use of ppoll() is just the same sequence of operations, but done atomically in the kernel, which prevents the mentioned race.
Kay