This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients giampaolo.rodola, neologix, pitrou, vstinner
Date 2011-06-08.22:28:59
SpamBayes Score 2.8310687e-15
Marked as misclassified No
Message-id <1307572140.77.0.125739321687.issue12187@psf.upfronthosting.co.za>
In-reply-to
Content
> To be portable, we would need to ...

Antoine is right: we don't have to be portable. We can write an "optimized" implementations (without polling) for a specific OS, even for a specific version of an OS (e.g. like Linux kernel >= 2.6.22 for signalfd).

I like the idea of signalfd(), but I don't know exactly how it works. Should we block the signal? What happens when we unblock the signal? It would be nice if the signal handler is called on unblock, because it would not change the current behaviour. Is it possible to block a signal in all threads? pthread_sigmask() blocks signals in the current thread, the manual page of sigprocmask() has a funny comment: "The use of sigprocmask() is unspecified in a multithreaded process; see pthread_sigmask(3)."

Extract of signalfd() manual page: "Normally,  the  set of signals to be received via the file descriptor should be blocked using sigprocmask(2), to prevent the signals being handled according to their default dispositions."

Is SIGCHLD only raised once at child process exit? "SIGCLD would be delivered constantly (unless blocked) while any child is ready to be waited for." according to http://lwn.net/Articles/414618/

> There's just one problem: SIGCHLD is ignored by default,
> which means that sigwait and friends won't return when a child exits.

sigwait() is not impacted by the associated signal handler, but sigwait() only works if the signal is blocked (e.g. by pthread_sigmask):

"If no signal in set is pending at the time of the call, the thread is suspended until one or more becomes pending. The signals defined by set will been blocked at the time of the call to sigwait(); otherwise the behaviour is undefined."
http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigwait.html

Example (for Python 3.3):
--------------------------
from signal import *
import subprocess

signum = SIGCHLD
process = subprocess.Popen("sleep 1", shell=True)
print("Wait %s..." % signum)
pthread_sigmask(SIG_BLOCK, [signum])
sigwait([signum])
pthread_sigmask(SIG_UNBLOCK, [signum])
print("done")
process.wait()
--------------------------

Same question than signalfd(): how can we block a signal in all threads (including C threads, e.g. _tkinter event looop thread)? Use sigprocmask()?

sigwait() removes the signal from the list of pending signals, so the signal handler will not be called.

> Note that exposing sigtimedwait is probably useful anyway,
> and I'd like to work on a patch.

See also issue #8407 for sigtimedwait() and signalfd() in Python.

---

sigprocmask(), sigwait() and signals in general seem to behave differently on each OS, so anyway, we cannot write a single portable implementation to solve this issue. If we cannot write a reliable non-polling implementation for an OS, you should use the polling implementation instead (which *is* reliable).
History
Date User Action Args
2011-06-08 22:29:00vstinnersetrecipients: + vstinner, pitrou, giampaolo.rodola, neologix
2011-06-08 22:29:00vstinnersetmessageid: <1307572140.77.0.125739321687.issue12187@psf.upfronthosting.co.za>
2011-06-08 22:29:00vstinnerlinkissue12187 messages
2011-06-08 22:28:59vstinnercreate