Page MenuHomePhabricator

D21058.diff
No OneTemporary

D21058.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -866,6 +866,7 @@
'phutil_decode_mime_header' => 'utils/utils.php',
'phutil_deprecated' => 'init/lib/moduleutils.php',
'phutil_describe_type' => 'utils/utils.php',
+ 'phutil_encode_log' => 'utils/utils.php',
'phutil_error_listener_example' => 'error/phlog.php',
'phutil_escape_uri' => 'utils/utils.php',
'phutil_escape_uri_path_component' => 'utils/utils.php',
diff --git a/src/channel/PhutilJSONProtocolChannel.php b/src/channel/PhutilJSONProtocolChannel.php
--- a/src/channel/PhutilJSONProtocolChannel.php
+++ b/src/channel/PhutilJSONProtocolChannel.php
@@ -43,7 +43,16 @@
* @task protocol
*/
protected function encodeMessage($message) {
- $message = json_encode($message);
+ if (!is_array($message)) {
+ throw new Exception(
+ pht(
+ 'JSON protocol message must be an array, got some other '.
+ 'type ("%s").',
+ phutil_describe_type($message)));
+ }
+
+ $message = phutil_json_encode($message);
+
$len = sprintf(
'%0'.self::SIZE_LENGTH.'.'.self::SIZE_LENGTH.'d',
strlen($message));
@@ -67,6 +76,21 @@
$len = substr($this->buf, 0, self::SIZE_LENGTH);
$this->buf = substr($this->buf, self::SIZE_LENGTH);
+ if (!preg_match('/^\d+\z/', $len)) {
+ $full_buffer = $len.$this->buf;
+ $full_length = strlen($full_buffer);
+
+ throw new Exception(
+ pht(
+ 'Protocol channel expected %s-character, zero-padded '.
+ 'numeric frame length, got something else ("%s"). Full '.
+ 'buffer (of length %s) begins: %s',
+ new PhutilNumber(self::SIZE_LENGTH),
+ phutil_encode_log($len),
+ new PhutilNumber($full_length),
+ phutil_encode_log(substr($len.$this->buf, 0, 128))));
+ }
+
$this->mode = self::MODE_OBJECT;
$this->byteLengthOfNextChunk = (int)$len;
break;
diff --git a/src/filesystem/PhutilDeferredLog.php b/src/filesystem/PhutilDeferredLog.php
--- a/src/filesystem/PhutilDeferredLog.php
+++ b/src/filesystem/PhutilDeferredLog.php
@@ -229,7 +229,7 @@
if ($saw_percent) {
$saw_percent = false;
if (array_key_exists($c, $map)) {
- $result .= addcslashes($map[$c], "\0..\37\\\177..\377");
+ $result .= phutil_encode_log($map[$c]);
} else {
$result .= '-';
}
diff --git a/src/future/FuturePool.php b/src/future/FuturePool.php
--- a/src/future/FuturePool.php
+++ b/src/future/FuturePool.php
@@ -34,6 +34,10 @@
return $this;
}
+ public function getFutures() {
+ return $this->futures;
+ }
+
public function hasFutures() {
return (bool)$this->futures;
}
diff --git a/src/phage/agent/PhagePHPAgent.php b/src/phage/agent/PhagePHPAgent.php
--- a/src/phage/agent/PhagePHPAgent.php
+++ b/src/phage/agent/PhagePHPAgent.php
@@ -4,27 +4,28 @@
private $stdin;
private $master;
- private $exec = array();
+ private $futurePool;
public function __construct($stdin) {
$this->stdin = $stdin;
}
public function execute() {
+ $future_pool = $this->getFuturePool();
+
while (true) {
- if ($this->exec) {
- $iterator = new FutureIterator($this->exec);
- $iterator->setUpdateInterval(0.050);
- foreach ($iterator as $key => $future) {
+ if ($future_pool->hasFutures()) {
+ while ($future_pool->hasFutures()) {
+ $future = $future_pool->resolve();
+
if ($future === null) {
- foreach ($this->exec as $read_key => $read_future) {
- $this->readFuture($read_key, $read_future);
+ foreach ($future_pool->getFutures() as $read_future) {
+ $this->readFuture($read_future);
}
-
break;
- } else {
- $this->resolveFuture($key, $future);
}
+
+ $this->resolveFuture($future);
}
} else {
PhutilChannel::waitForAny(array($this->getMaster()));
@@ -34,6 +35,22 @@
}
}
+ private function getFuturePool() {
+ if (!$this->futurePool) {
+ $this->futurePool = $this->newFuturePool();
+ }
+ return $this->futurePool;
+ }
+
+ private function newFuturePool() {
+ $future_pool = new FuturePool();
+
+ $future_pool->getIteratorTemplate()
+ ->setUpdateInterval(0.050);
+
+ return $future_pool;
+ }
+
private function getMaster() {
if (!$this->master) {
$raw_channel = new PhutilSocketChannel(
@@ -77,9 +94,10 @@
$future->setTimeout(ceil($timeout));
}
- $future->isReady();
+ $future->setFutureKey($key);
- $this->exec[$key] = $future;
+ $this->getFuturePool()
+ ->addFuture($future);
break;
case 'EXIT':
$this->terminateAgent();
@@ -87,8 +105,9 @@
}
}
- private function readFuture($key, ExecFuture $future) {
+ private function readFuture(ExecFuture $future) {
$master = $this->getMaster();
+ $key = $future->getFutureKey();
list($stdout, $stderr) = $future->read();
$future->discardBuffers();
@@ -114,7 +133,8 @@
}
}
- private function resolveFuture($key, ExecFuture $future) {
+ private function resolveFuture(ExecFuture $future) {
+ $key = $future->getFutureKey();
$result = $future->resolve();
$master = $this->getMaster();
@@ -127,8 +147,6 @@
'stderr' => $result[2],
'timeout' => (bool)$future->getWasKilledByTimeout(),
));
-
- unset($this->exec[$key]);
}
public function __destruct() {
@@ -136,9 +154,12 @@
}
private function terminateAgent() {
- foreach ($this->exec as $key => $future) {
+ $pool = $this->getFuturePool();
+
+ foreach ($pool->getFutures() as $future) {
$future->resolveKill();
}
+
exit(0);
}
diff --git a/src/phage/bootloader/PhagePHPAgentBootloader.php b/src/phage/bootloader/PhagePHPAgentBootloader.php
--- a/src/phage/bootloader/PhagePHPAgentBootloader.php
+++ b/src/phage/bootloader/PhagePHPAgentBootloader.php
@@ -47,6 +47,7 @@
'xsprintf/PhutilCommandString.php',
'future/Future.php',
'future/FutureIterator.php',
+ 'future/FuturePool.php',
'future/exec/PhutilExecutableFuture.php',
'future/exec/ExecFuture.php',
'future/exec/CommandException.php',
diff --git a/src/utils/utils.php b/src/utils/utils.php
--- a/src/utils/utils.php
+++ b/src/utils/utils.php
@@ -1926,3 +1926,7 @@
return false;
}
+
+function phutil_encode_log($message) {
+ return addcslashes($message, "\0..\37\\\177..\377");
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 1:51 AM (18 h, 14 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6784611
Default Alt Text
D21058.diff (6 KB)

Event Timeline