Mercurial > hg > isophonics-drupal-site
comparison vendor/psy/psysh/src/ExecutionLoop/ProcessForker.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | c2387f117808 |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
31 * | 31 * |
32 * @return bool | 32 * @return bool |
33 */ | 33 */ |
34 public static function isSupported() | 34 public static function isSupported() |
35 { | 35 { |
36 return function_exists('pcntl_signal') && function_exists('posix_getpid'); | 36 return \function_exists('pcntl_signal') && \function_exists('posix_getpid'); |
37 } | 37 } |
38 | 38 |
39 /** | 39 /** |
40 * Forks into a master and a loop process. | 40 * Forks into a master and a loop process. |
41 * | 41 * |
44 * | 44 * |
45 * @param Shell $shell | 45 * @param Shell $shell |
46 */ | 46 */ |
47 public function beforeRun(Shell $shell) | 47 public function beforeRun(Shell $shell) |
48 { | 48 { |
49 list($up, $down) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); | 49 list($up, $down) = \stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); |
50 | 50 |
51 if (!$up) { | 51 if (!$up) { |
52 throw new \RuntimeException('Unable to create socket pair'); | 52 throw new \RuntimeException('Unable to create socket pair'); |
53 } | 53 } |
54 | 54 |
55 $pid = pcntl_fork(); | 55 $pid = \pcntl_fork(); |
56 if ($pid < 0) { | 56 if ($pid < 0) { |
57 throw new \RuntimeException('Unable to start execution loop'); | 57 throw new \RuntimeException('Unable to start execution loop'); |
58 } elseif ($pid > 0) { | 58 } elseif ($pid > 0) { |
59 // This is the main thread. We'll just wait for a while. | 59 // This is the main thread. We'll just wait for a while. |
60 | 60 |
61 // We won't be needing this one. | 61 // We won't be needing this one. |
62 fclose($up); | 62 \fclose($up); |
63 | 63 |
64 // Wait for a return value from the loop process. | 64 // Wait for a return value from the loop process. |
65 $read = [$down]; | 65 $read = [$down]; |
66 $write = null; | 66 $write = null; |
67 $except = null; | 67 $except = null; |
68 | 68 |
69 do { | 69 do { |
70 $n = @stream_select($read, $write, $except, null); | 70 $n = @\stream_select($read, $write, $except, null); |
71 | 71 |
72 if ($n === 0) { | 72 if ($n === 0) { |
73 throw new \RuntimeException('Process timed out waiting for execution loop'); | 73 throw new \RuntimeException('Process timed out waiting for execution loop'); |
74 } | 74 } |
75 | 75 |
76 if ($n === false) { | 76 if ($n === false) { |
77 $err = error_get_last(); | 77 $err = \error_get_last(); |
78 if (!isset($err['message']) || stripos($err['message'], 'interrupted system call') === false) { | 78 if (!isset($err['message']) || \stripos($err['message'], 'interrupted system call') === false) { |
79 $msg = $err['message'] ? | 79 $msg = $err['message'] ? |
80 sprintf('Error waiting for execution loop: %s', $err['message']) : | 80 \sprintf('Error waiting for execution loop: %s', $err['message']) : |
81 'Error waiting for execution loop'; | 81 'Error waiting for execution loop'; |
82 throw new \RuntimeException($msg); | 82 throw new \RuntimeException($msg); |
83 } | 83 } |
84 } | 84 } |
85 } while ($n < 1); | 85 } while ($n < 1); |
86 | 86 |
87 $content = stream_get_contents($down); | 87 $content = \stream_get_contents($down); |
88 fclose($down); | 88 \fclose($down); |
89 | 89 |
90 if ($content) { | 90 if ($content) { |
91 $shell->setScopeVariables(@unserialize($content)); | 91 $shell->setScopeVariables(@\unserialize($content)); |
92 } | 92 } |
93 | 93 |
94 throw new BreakException('Exiting main thread'); | 94 throw new BreakException('Exiting main thread'); |
95 } | 95 } |
96 | 96 |
97 // This is the child process. It's going to do all the work. | 97 // This is the child process. It's going to do all the work. |
98 if (function_exists('setproctitle')) { | 98 if (\function_exists('setproctitle')) { |
99 setproctitle('psysh (loop)'); | 99 setproctitle('psysh (loop)'); |
100 } | 100 } |
101 | 101 |
102 // We won't be needing this one. | 102 // We won't be needing this one. |
103 fclose($down); | 103 \fclose($down); |
104 | 104 |
105 // Save this; we'll need to close it in `afterRun` | 105 // Save this; we'll need to close it in `afterRun` |
106 $this->up = $up; | 106 $this->up = $up; |
107 } | 107 } |
108 | 108 |
123 */ | 123 */ |
124 public function afterLoop(Shell $shell) | 124 public function afterLoop(Shell $shell) |
125 { | 125 { |
126 // if there's an old savegame hanging around, let's kill it. | 126 // if there's an old savegame hanging around, let's kill it. |
127 if (isset($this->savegame)) { | 127 if (isset($this->savegame)) { |
128 posix_kill($this->savegame, SIGKILL); | 128 \posix_kill($this->savegame, SIGKILL); |
129 pcntl_signal_dispatch(); | 129 \pcntl_signal_dispatch(); |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 /** | 133 /** |
134 * After the REPL session ends, send the scope variables back up to the main | 134 * After the REPL session ends, send the scope variables back up to the main |
138 */ | 138 */ |
139 public function afterRun(Shell $shell) | 139 public function afterRun(Shell $shell) |
140 { | 140 { |
141 // We're a child thread. Send the scope variables back up to the main thread. | 141 // We're a child thread. Send the scope variables back up to the main thread. |
142 if (isset($this->up)) { | 142 if (isset($this->up)) { |
143 fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false))); | 143 \fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false))); |
144 fclose($this->up); | 144 \fclose($this->up); |
145 | 145 |
146 posix_kill(posix_getpid(), SIGKILL); | 146 \posix_kill(\posix_getpid(), SIGKILL); |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 /** | 150 /** |
151 * Create a savegame fork. | 151 * Create a savegame fork. |
155 * a PHP fatal error). | 155 * a PHP fatal error). |
156 */ | 156 */ |
157 private function createSavegame() | 157 private function createSavegame() |
158 { | 158 { |
159 // the current process will become the savegame | 159 // the current process will become the savegame |
160 $this->savegame = posix_getpid(); | 160 $this->savegame = \posix_getpid(); |
161 | 161 |
162 $pid = pcntl_fork(); | 162 $pid = \pcntl_fork(); |
163 if ($pid < 0) { | 163 if ($pid < 0) { |
164 throw new \RuntimeException('Unable to create savegame fork'); | 164 throw new \RuntimeException('Unable to create savegame fork'); |
165 } elseif ($pid > 0) { | 165 } elseif ($pid > 0) { |
166 // we're the savegame now... let's wait and see what happens | 166 // we're the savegame now... let's wait and see what happens |
167 pcntl_waitpid($pid, $status); | 167 \pcntl_waitpid($pid, $status); |
168 | 168 |
169 // worker exited cleanly, let's bail | 169 // worker exited cleanly, let's bail |
170 if (!pcntl_wexitstatus($status)) { | 170 if (!\pcntl_wexitstatus($status)) { |
171 posix_kill(posix_getpid(), SIGKILL); | 171 \posix_kill(\posix_getpid(), SIGKILL); |
172 } | 172 } |
173 | 173 |
174 // worker didn't exit cleanly, we'll need to have another go | 174 // worker didn't exit cleanly, we'll need to have another go |
175 $this->createSavegame(); | 175 $this->createSavegame(); |
176 } | 176 } |
197 if (Context::isSpecialVariableName($key)) { | 197 if (Context::isSpecialVariableName($key)) { |
198 continue; | 198 continue; |
199 } | 199 } |
200 | 200 |
201 // Resources and Closures don't error, but they don't serialize well either. | 201 // Resources and Closures don't error, but they don't serialize well either. |
202 if (is_resource($value) || $value instanceof \Closure) { | 202 if (\is_resource($value) || $value instanceof \Closure) { |
203 continue; | 203 continue; |
204 } | 204 } |
205 | 205 |
206 try { | 206 try { |
207 @serialize($value); | 207 @\serialize($value); |
208 $serializable[$key] = $value; | 208 $serializable[$key] = $value; |
209 } catch (\Throwable $e) { | 209 } catch (\Throwable $e) { |
210 // we'll just ignore this one... | 210 // we'll just ignore this one... |
211 } catch (\Exception $e) { | 211 } catch (\Exception $e) { |
212 // and this one too... | 212 // and this one too... |
213 // @todo remove this once we don't support PHP 5.x anymore :) | 213 // @todo remove this once we don't support PHP 5.x anymore :) |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 return @serialize($serializable); | 217 return @\serialize($serializable); |
218 } | 218 } |
219 } | 219 } |