Skip to content

Commit

Permalink
[Process] Refactor the windows handling so it is always executed
Browse files Browse the repository at this point in the history
When regular pipes are closed, the file handlers fallback on windows
should still be processed until they are empty
  • Loading branch information
Seldaek committed May 24, 2012
1 parent 0c5aa8b commit bcf8cf9
Showing 1 changed file with 60 additions and 58 deletions.
118 changes: 60 additions & 58 deletions src/Symfony/Component/Process/Process.php
Expand Up @@ -206,6 +206,9 @@ public function start($callback = null)
$this->fileHandles = array(
self::STDOUT => tmpfile(),
);
$this->readBytes = array(
self::STDOUT => 0,
);
$descriptors = array(array('pipe', 'r'), $this->fileHandles[self::STDOUT], array('pipe', 'w'));
} else {
$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
Expand Down Expand Up @@ -236,14 +239,18 @@ public function start($callback = null)
unset($this->pipes[0]);

return;
} else {
$writePipes = array($this->pipes[0]);
unset($this->pipes[0]);
$stdinLen = strlen($this->stdin);
$stdinOffset = 0;
}

$writePipes = array($this->pipes[0]);
unset($this->pipes[0]);
$stdinLen = strlen($this->stdin);
$stdinOffset = 0;

while ($writePipes) {
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->processFileHandles($callback);
}

$r = $this->pipes;
$w = $writePipes;
$e = null;
Expand All @@ -252,7 +259,8 @@ public function start($callback = null)

if (false === $n) {
break;
} elseif ($n === 0) {
}
if ($n === 0) {
proc_terminate($this->process);

throw new \RuntimeException('The process timed out.');
Expand All @@ -269,22 +277,6 @@ public function start($callback = null)
}
}

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$fh = $this->fileHandles;
foreach ($fh as $type => $fileHandle) {
fseek($fileHandle, 0);
$data = fread($fileHandle, 8192);
$this->readBytes[$type] = strlen($data);
if (strlen($data) > 0) {
call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data);
}
if (false === $data) {
fclose($fileHandle);
unset($this->fileHandles[$type]);
}
}
}

foreach ($r as $pipe) {
$type = array_search($pipe, $this->pipes);
$data = fread($pipe, 8192);
Expand Down Expand Up @@ -319,53 +311,40 @@ public function wait($callback = null)
$this->processInformation = proc_get_status($this->process);
$callback = $this->buildCallback($callback);
while ($this->pipes || (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles)) {
$r = $this->pipes;
$w = null;
$e = null;
if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles) {
$this->processFileHandles($callback, !$this->pipes);
}

$n = @stream_select($r, $w, $e, $this->timeout);
if ($this->pipes) {
$r = $this->pipes;
$w = null;
$e = null;

if (false === $n) {
break;
}
if (0 === $n) {
proc_terminate($this->process);
$n = @stream_select($r, $w, $e, $this->timeout);

throw new \RuntimeException('The process timed out.');
}
if (false === $n) {
$this->pipes = array();

if (defined('PHP_WINDOWS_VERSION_BUILD')) {
$fh = $this->fileHandles;
foreach ($fh as $type => $fileHandle) {
fseek($fileHandle, $this->readBytes[$type]);
$data = fread($fileHandle, 8192);
if (isset($this->readBytes)) {
$this->readBytes[$type] += strlen($data);
} else {
$this->readBytes[$type] = strlen($data);
}
continue;
}
if (0 === $n) {
proc_terminate($this->process);

throw new \RuntimeException('The process timed out.');
}

foreach ($r as $pipe) {
$type = array_search($pipe, $this->pipes);
$data = fread($pipe, 8192);
if (strlen($data) > 0) {
call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data);
}
if (false === $data) {
fclose($fileHandle);
unset($this->fileHandles[$type]);
if (false === $data || feof($pipe)) {
fclose($pipe);
unset($this->pipes[$type]);
}
}
}

foreach ($r as $pipe) {
$type = array_search($pipe, $this->pipes);
$data = fread($pipe, 8192);
if (strlen($data) > 0) {
call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data);
}
if (false === $data || feof($pipe)) {
fclose($pipe);
unset($this->pipes[$type]);
}
}
}
$this->updateStatus();
if ($this->processInformation['signaled']) {
Expand Down Expand Up @@ -725,4 +704,27 @@ protected function updateOutput()
$this->addOutput(stream_get_contents($this->pipes[self::STDOUT]));
}
}

/**
* Handles the windows file handles fallbacks
*
* @param mixed $callback A valid PHP callback
* @param Boolean $closeEmptyHandles if true, handles that are empty will be assumed closed
*/
private function processFileHandles($callback, $closeEmptyHandles = false)
{
$fh = $this->fileHandles;
foreach ($fh as $type => $fileHandle) {
fseek($fileHandle, $this->readBytes[$type]);
$data = fread($fileHandle, 8192);
if (strlen($data) > 0) {
$this->readBytes[$type] += strlen($data);
call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data);
}
if (false === $data || ($closeEmptyHandles && '' === $data && feof($fileHandle))) {
fclose($fileHandle);
unset($this->fileHandles[$type]);
}
}
}
}

0 comments on commit bcf8cf9

Please sign in to comment.