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 Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Process
private $incrementalErrorOutputOffset;

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

private static $sigchild;
Expand Down Expand Up @@ -304,30 +305,20 @@ public function wait($callback = null)
if (null !== $callback) {
$this->callback = $this->buildCallback($callback);
}
while ($this->processInformation['running']) {

do {
$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();
$exitcode = proc_close($this->process);

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

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

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

$this->readPipes($blocking);

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

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

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

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

0 comments on commit 2ab8127

Please sign in to comment.