Skip to content

Commit

Permalink
[Process] Fix #9182 : random failure on pipes tests
Browse files Browse the repository at this point in the history
  • Loading branch information
romainneutron committed Oct 9, 2013
1 parent 01ec66b commit 2ab8127
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 28 deletions.
49 changes: 23 additions & 26 deletions Process.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Process
private $incrementalErrorOutputOffset; private $incrementalErrorOutputOffset;


private $useFileHandles = false; private $useFileHandles = false;
/** @var ProcessPipes */
private $processPipes; private $processPipes;


private static $sigchild; private static $sigchild;
Expand Down Expand Up @@ -304,30 +305,20 @@ public function wait($callback = null)
if (null !== $callback) { if (null !== $callback) {
$this->callback = $this->buildCallback($callback); $this->callback = $this->buildCallback($callback);
} }
while ($this->processInformation['running']) {
do {
$this->checkTimeout(); $this->checkTimeout();
$this->updateStatus(true); $running = defined('PHP_WINDOWS_VERSION_BUILD') ? $this->isRunning() : $this->processPipes->hasOpenHandles();
$close = !defined('PHP_WINDOWS_VERSION_BUILD') || !$running;;
$this->readPipes(true, $close);
} while ($running);

while ($this->isRunning()) {
usleep(1000);
} }
$this->updateStatus(false);

// Unix pipes must be closed before calling proc_close to void deadlock
// see manual http://php.net/manual/en/function.proc-close.php
$this->processPipes->closeUnixPipes();
$exitcode = proc_close($this->process);


// Windows only : when using file handles, some activity may occur after
// calling proc_close
while($this->processPipes->hasOpenHandles()) {
usleep(100);
foreach ($this->processPipes->readAndCloseHandles(true) as $type => $data) {
if (3 == $type) {
$this->fallbackExitcode = (int) $data;
} else {
call_user_func($this->callback, $type === self::STDOUT ? self::OUT : self::ERR, $data);
}
}
}
$this->processPipes->close(); $this->processPipes->close();
$exitcode = proc_close($this->process);


if ($this->processInformation['signaled']) { if ($this->processInformation['signaled']) {
if ($this->isSigchildEnabled()) { if ($this->isSigchildEnabled()) {
Expand Down Expand Up @@ -355,7 +346,7 @@ public function wait($callback = null)
*/ */
public function getOutput() public function getOutput()
{ {
$this->readPipes(false); $this->readPipes(false, defined('PHP_WINDOWS_VERSION_BUILD') ? !$this->processInformation['running'] : true);


return $this->stdout; return $this->stdout;
} }
Expand Down Expand Up @@ -387,7 +378,7 @@ public function getIncrementalOutput()
*/ */
public function getErrorOutput() public function getErrorOutput()
{ {
$this->readPipes(false); $this->readPipes(false, defined('PHP_WINDOWS_VERSION_BUILD') ? !$this->processInformation['running'] : true);


return $this->stderr; return $this->stderr;
} }
Expand Down Expand Up @@ -932,9 +923,9 @@ protected function updateStatus($blocking)
return; return;
} }


$this->readPipes($blocking);

$this->processInformation = proc_get_status($this->process); $this->processInformation = proc_get_status($this->process);
$this->readPipes($blocking, defined('PHP_WINDOWS_VERSION_BUILD') ? !$this->processInformation['running'] : true);

if (!$this->processInformation['running']) { if (!$this->processInformation['running']) {
$this->status = self::STATUS_TERMINATED; $this->status = self::STATUS_TERMINATED;
if (-1 !== $this->processInformation['exitcode']) { if (-1 !== $this->processInformation['exitcode']) {
Expand Down Expand Up @@ -965,9 +956,15 @@ protected function isSigchildEnabled()
* *
* @param Boolean $blocking Whether to use blocking calls or not. * @param Boolean $blocking Whether to use blocking calls or not.
*/ */
private function readPipes($blocking) private function readPipes($blocking, $close)
{ {
foreach ($this->processPipes->read($blocking) as $type => $data) { if ($close) {
$result = $this->processPipes->readAndCloseHandles($blocking);
} else {
$result = $this->processPipes->read($blocking);
}

foreach ($result as $type => $data) {
if (3 == $type) { if (3 == $type) {
$this->fallbackExitcode = (int) $data; $this->fallbackExitcode = (int) $data;
} else { } else {
Expand Down
5 changes: 3 additions & 2 deletions ProcessPipes.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ private function readFileHandles($close = false)
continue; continue;
} }
$data = ''; $data = '';
$dataread = null;
while (!feof($fileHandle)) { while (!feof($fileHandle)) {
if (false !== $dataread = fread($fileHandle, 16392)) { if (false !== $dataread = fread($fileHandle, 16392)) {
$data .= $dataread; $data .= $dataread;
Expand All @@ -232,7 +233,7 @@ private function readFileHandles($close = false)
$read[$type] = $data; $read[$type] = $data;
} }


if (true === $close && feof($fileHandle)) { if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) {
fclose($this->fileHandles[$type]); fclose($this->fileHandles[$type]);
unset($this->fileHandles[$type]); unset($this->fileHandles[$type]);
} }
Expand Down Expand Up @@ -280,7 +281,7 @@ private function readStreams($blocking, $close = false)
$read[$type] = $data; $read[$type] = $data;
} }


if (true === $close && feof($pipe)) { if (false === $data || (true === $close && feof($pipe) && '' === $data)) {
fclose($this->pipes[$type]); fclose($this->pipes[$type]);
unset($this->pipes[$type]); unset($this->pipes[$type]);
} }
Expand Down

0 comments on commit 2ab8127

Please sign in to comment.