ipython/ipython — pull request #2369 by epatters (2012-08-31 18:33:29+00:00)
Title: Block until kernel termination after sending a kill signal

As users of the Qt console have probably noticed, restarting the kernel is not as reliable as it ought to be. In some cases, a second restart seems to fix the problem; in other cases, the frontend itself becomes wedged. I am currently investigating these problems.

In trying to reproduce these problems, one thing that I noticed immediately is that restarting the kernel via a kill (rather than a clean shutdown) often fails, at least OS X. Try this:

1. Change ``now=False`` to ``now=True`` in https://github.com/ipython/ipython/blob/master/IPython/frontend/qt/console/frontend_widget.py#L273
2. Attempt to restart the kernel (Ctrl+.)

Usually, I get the following traceback in the frontend process:

```
Traceback (most recent call last):
File "/Users/epatters/Local/IPython/IPython/frontend/qt/console/mainwindow.py", line 836, in restart_kernel_active_frontend
self.active_frontend.request_restart_kernel()
File "/Users/epatters/Local/IPython/IPython/frontend/qt/console/frontend_widget.py", line 273, in request_restart_kernel
self.restart_kernel(message, now=False)
File "/Users/epatters/Local/IPython/IPython/frontend/qt/console/frontend_widget.py", line 635, in restart_kernel
self.kernel_manager.restart_kernel(now=now)
File "/Users/epatters/Local/IPython/IPython/zmq/kernelmanager.py", line 882, in restart_kernel
self.start_kernel(**self._launch_args)
File "/Users/epatters/Local/IPython/IPython/frontend/qt/kernelmanager.py", line 211, in start_kernel
super(QtKernelManager, self).start_kernel(*args, **kw)
File "/Users/epatters/Local/IPython/IPython/zmq/kernelmanager.py", line 812, in start_kernel
self.kernel = launch_kernel(fname=self.connection_file, **kw)
File "/Users/epatters/Local/IPython/IPython/zmq/ipkernel.py", line 878, in launch_kernel
*args, **kwargs)
File "/Users/epatters/Local/IPython/IPython/zmq/entry_point.py", line 200, in base_launch_kernel
stdin=_stdin, stdout=_stdout, stderr=_stderr, cwd=cwd)
File "/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/subprocess.py", line 1234, in _execute_child
data = _eintr_retry_call(os.read, errpipe_read, 1048576)
File "/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/subprocess.py", line 478, in _eintr_retry_call
return func(*args)
OSError: [Errno 22] Invalid argument
```

Now, this error is quite obscure and I don't really understand what is going on here, but I think the problem is that the new kernel is sometimes started before the old kernel has actually terminated. In any event, waiting for the kernel to terminate before continuing seems to fix the problem.

My only concern with this PR is that blocking calls without timeouts make me a little nervous. If, for some reason, the kernel survives SIGKILL, the frontend application will deadlock. Is this a reasonable concern in practice?