On 03:27 pm, a...@roiban.ro wrote:
On 3 September 2014 14:39,  <exar...@twistedmatrix.com> wrote:

Yes. Providing more fine-grain control over signal handlers would be a fine
improvement.

Do you have any suggestion for how the calls should be made?

reactor.run(installSignalHandlers=True,  installStopHandlers=False)

Perhaps.
or

reactor.installStopHandlers = False
reactor.run()

Probably not this one. Setting attributes on random things is kind of sad. :)

It might be nice to try to be somewhat flexible - in case there's some reason to change what signals the reactor wants to handle in the future. Perhaps:

   reactor.run(installSignalHandlers={SIGCHLD})

An entirely different direction could be to make this bit of configuration into initialization for the reactor.

   from twisted.internet.epollreactor import install
   install(installSignalHandlers={SIGCHLD})

   from twisted.internet import reactor
   ...
   reactor.run()

By keeping these details away from `IReactorCore.run`, that method remains maximally useful. For example, if you could set up the reactor this way, a normal `twistd` plugin would still be able to benefit from your choice, even with twistd's naive call of `reactor.run()` with no extra arguments.

Application code calling these `install` functions is already supported (it's how you select a specific reactor, after all). Some of the install functions even accept arguments already.

This would actually eliminate another existing issue - `IReactorCore.run` is actually defined to take no arguments. The implementations ignore this because someone thought it was important to be able to disable installation of signal handlers.

Another fine improvement would be making child processes work even if a
SIGCHLD handler cannot be installed (for example, by polling children
periodically, by using wait() in a sidecar process, or by using a better system-specific child process monitoring API (eg kqueue's EVFILT_PROC)).

I see that GlibReactorBase inherits from PosixReactorBase so it should
install the SIGCHLD handler... this should not be the reason why gtk2
reactor don't work.

Gtk messes with signals too. There are confusing order-of-execution dependencies and Gtk changes subtly from release to release, re-breaking things after we fix them or changing them to be broken in a different way.

So that's *why* it probably doesn't work with Gtk2 reactor - if not *how*. ;)

I think I missed the explanation of what in particular wasn't working with Gtk2 reactor though.
As a poor man's fix and Unix independent fix maybe we can call
reapAllProcess in a task.LoopingCall...
What are the reasons why SIGCHLD handler cannot be installed?

Either because you want to run the reactor in a non-main thread (where Python won't let you install signal handlers for the good reason that mixing signals and threads has crazy behavior) or because you want to use a different library that depends on having its own SIGCHLD handler and you're not interested in Twisted's process support.
I am asking since I hope it could help me understant where and how to
enable the poor man's fix... and how to fill the bug report.

kqueue's EVFILT_PROC would be great, but I guess that we still need a
general fix

Perhaps, perhaps not. A general fix might be less code but having half a dozen specialized fixes, one for each reactor, would also still fix the problem. The different reactor implementations are essentially the big piles of specialized fixes needed to do non-blocking I/O on different platforms. This would just be a little more of the same.

The sidecar process is an example of a general fix, though. The idea there is that Twisted itself runs a private child process (perhaps only when the first call to spawnProcess is made). It talks to that process using a file descriptor. That process can install a SIGCHLD handler (because Twisted owns it, application developers don't get to say they don't want one installed) or use another more invasive strategy for child process management. When you want to spawn a process, the main process tells the sidecar to do it. The sidecar relays traffic between the child and the original parent (or does something involving passing file descriptors across processes).

This removes the need to ever install a SIGCHLD handler in the main process. It also probably enables some optimizations (reapProcesses is O(N!) on the number of child processes right now) that are very tricky or impossible otherwise.

Jean-Paul
---------

For the record: Right now, to ignore SIGINT, SIGTERM, SIGBREAK handles
but keep SIGCHLD I do:

# Patch base reactor to not install SIGINT, SIGTERM and SIGBREAK handlers
_SignalReactorMixin._handleSignals = lambda self: None
reactor.run()


--
Adi Roiban

_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to