Skip to content

Commit 173f8c5

Browse files
committed
[Process] Avoid failure when calling Process::stop in edge cases
See https://travis-ci.org/symfony/symfony/jobs/20664994 for an example of failure.
1 parent 123dcac commit 173f8c5

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

src/Symfony/Component/Process/Process.php

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,7 @@ public function getPid()
356356
*/
357357
public function signal($signal)
358358
{
359-
if (!$this->isRunning()) {
360-
throw new LogicException('Can not send signal on a non running process.');
361-
}
362-
363-
if ($this->isSigchildEnabled()) {
364-
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
365-
}
366-
367-
if (true !== @proc_terminate($this->process, $signal)) {
368-
throw new RuntimeException(sprintf('Error while sending signal `%d`.', $signal));
369-
}
359+
$this->doSignal($signal, true);
370360

371361
return $this;
372362
}
@@ -635,7 +625,11 @@ public function stop($timeout = 10, $signal = null)
635625

636626
if ($this->isRunning() && !$this->isSigchildEnabled()) {
637627
if (null !== $signal || defined('SIGKILL')) {
638-
$this->signal($signal ?: SIGKILL);
628+
// avoid exception here :
629+
// process is supposed to be running, but it might have stop
630+
// just after this line.
631+
// in any case, let's silently discard the error, we can not do anything
632+
$this->doSignal($signal ?: SIGKILL, false);
639633
}
640634
}
641635
}
@@ -1111,4 +1105,44 @@ private function resetProcessData()
11111105
$this->incrementalOutputOffset = 0;
11121106
$this->incrementalErrorOutputOffset = 0;
11131107
}
1108+
1109+
/**
1110+
* Sends a POSIX signal to the process.
1111+
*
1112+
* @param integer $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
1113+
* @param Boolean $throwException True to throw exception in case signal failed, false otherwise
1114+
* @return Boolean True if the signal was sent successfully, false otherwise
1115+
*
1116+
* @throws LogicException In case the process is not running
1117+
* @throws RuntimeException In case --enable-sigchild is activated
1118+
* @throws RuntimeException In case of failure
1119+
*/
1120+
private function doSignal($signal, $throwException)
1121+
{
1122+
if (!$this->isRunning()) {
1123+
if ($throwException) {
1124+
throw new LogicException('Can not send signal on a non running process.');
1125+
}
1126+
1127+
return false;
1128+
}
1129+
1130+
if ($this->isSigchildEnabled()) {
1131+
if ($throwException) {
1132+
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
1133+
}
1134+
1135+
return false;
1136+
}
1137+
1138+
if (true !== @proc_terminate($this->process, $signal)) {
1139+
if ($throwException) {
1140+
throw new RuntimeException(sprintf('Error while sending signal `%d`.', $signal));
1141+
}
1142+
1143+
return false;
1144+
}
1145+
1146+
return true;
1147+
}
11141148
}

0 commit comments

Comments
 (0)