##// END OF EJS Templates
BUG: Ensure that kernel can be spawned from a backgrounded process.
epatters -
Show More
@@ -85,30 +85,37 b' def base_launch_kernel(code, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0'
85 executable = sys.executable
85 executable = sys.executable
86 arguments = [ executable, '-c', code, '--shell=%i'%shell_port,
86 arguments = [ executable, '-c', code, '--shell=%i'%shell_port,
87 '--iopub=%i'%iopub_port, '--stdin=%i'%stdin_port,
87 '--iopub=%i'%iopub_port, '--stdin=%i'%stdin_port,
88 '--hb=%i'%hb_port
88 '--hb=%i'%hb_port ]
89 ]
90 if ip is not None:
89 if ip is not None:
91 arguments.append('--ip=%s'%ip)
90 arguments.append('--ip=%s'%ip)
92 arguments.extend(extra_arguments)
91 arguments.extend(extra_arguments)
93
92
93 # Popen will fail (sometimes with a deadlock) if stdin, stdout, and stderr
94 # are invalid. Unfortunately, there is in general no way to detect whether
95 # they are valid. The following two blocks redirect them to (temporary)
96 # pipes in certain important cases.
97
98 # If this process has been backgrounded, our stdin is invalid. Since there
99 # is no compelling reason for the kernel to inherit our stdin anyway, we'll
100 # place this one safe and always redirect.
101 redirect_in = True
102 _stdin = PIPE if stdin is None else stdin
103
104 # If this process in running on pythonw, we know that stdin, stdout, and
105 # stderr are all invalid.
106 redirect_out = sys.executable.endswith('pythonw.exe')
107 if redirect_out:
108 _stdout = PIPE if stdout is None else stdout
109 _stderr = PIPE if stderr is None else stderr
110 else:
111 _stdout, _stderr = stdout, stderr
112
94 # Spawn a kernel.
113 # Spawn a kernel.
95 if sys.platform == 'win32':
114 if sys.platform == 'win32':
96 # Create a Win32 event for interrupting the kernel.
115 # Create a Win32 event for interrupting the kernel.
97 interrupt_event = ParentPollerWindows.create_interrupt_event()
116 interrupt_event = ParentPollerWindows.create_interrupt_event()
98 arguments += [ '--interrupt=%i'%interrupt_event ]
117 arguments += [ '--interrupt=%i'%interrupt_event ]
99
118
100 # If this process in running on pythonw, stdin, stdout, and stderr are
101 # invalid. Popen will fail unless they are suitably redirected. We don't
102 # read from the pipes, but they must exist.
103 if sys.executable.endswith('pythonw.exe'):
104 redirect = True
105 _stdin = PIPE if stdin is None else stdin
106 _stdout = PIPE if stdout is None else stdout
107 _stderr = PIPE if stderr is None else stderr
108 else:
109 redirect = False
110 _stdin, _stdout, _stderr = stdin, stdout, stderr
111
112 # If the kernel is running on pythonw and stdout/stderr are not been
119 # If the kernel is running on pythonw and stdout/stderr are not been
113 # re-directed, it will crash when more than 4KB of data is written to
120 # re-directed, it will crash when more than 4KB of data is written to
114 # stdout or stderr. This is a bug that has been with Python for a very
121 # stdout or stderr. This is a bug that has been with Python for a very
@@ -139,20 +146,22 b' def base_launch_kernel(code, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0'
139 # Attach the interrupt event to the Popen objet so it can be used later.
146 # Attach the interrupt event to the Popen objet so it can be used later.
140 proc.win32_interrupt_event = interrupt_event
147 proc.win32_interrupt_event = interrupt_event
141
148
142 # Clean up pipes created to work around Popen bug.
143 if redirect:
144 if stdin is None:
145 proc.stdin.close()
146 if stdout is None:
147 proc.stdout.close()
148 if stderr is None:
149 proc.stderr.close()
150
151 else:
149 else:
152 if independent:
150 if independent:
153 proc = Popen(arguments, preexec_fn=lambda: os.setsid(),
151 proc = Popen(arguments, preexec_fn=lambda: os.setsid(),
154 stdin=stdin, stdout=stdout, stderr=stderr)
152 stdin=_stdin, stdout=_stdout, stderr=_stderr)
155 else:
153 else:
156 proc = Popen(arguments + ['--parent=1'],
154 proc = Popen(arguments + ['--parent=1'],
157 stdin=stdin, stdout=stdout, stderr=stderr)
155 stdin=_stdin, stdout=_stdout, stderr=_stderr)
156
157 # Clean up pipes created to work around Popen bug.
158 if redirect_in:
159 if stdin is None:
160 proc.stdin.close()
161 if redirect_out:
162 if stdout is None:
163 proc.stdout.close()
164 if stderr is None:
165 proc.stderr.close()
166
158 return proc, shell_port, iopub_port, stdin_port, hb_port
167 return proc, shell_port, iopub_port, stdin_port, hb_port
General Comments 0
You need to be logged in to leave comments. Login now