Page MenuHomePhabricator

D7552.id17041.diff
No OneTemporary

D7552.id17041.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -373,6 +373,7 @@
'phutil_safe_html' => 'markup/render.php',
'phutil_split_lines' => 'utils/utils.php',
'phutil_tag' => 'markup/render.php',
+ 'phutil_tag_div' => 'markup/render.php',
'phutil_unescape_uri_path_component' => 'markup/render.php',
'phutil_utf8_console_strlen' => 'utils/utf8.php',
'phutil_utf8_convert' => 'utils/utf8.php',
@@ -400,6 +401,7 @@
'vqsprintf' => 'xsprintf/qsprintf.php',
'vqueryfx' => 'xsprintf/queryfx.php',
'vqueryfx_all' => 'xsprintf/queryfx.php',
+ 'vurisprintf' => 'xsprintf/urisprintf.php',
'xhp_parser_node_constants' => 'parser/xhpast/parser_nodes.php',
'xhpast_get_binary_path' => 'parser/xhpast/bin/xhpast_parse.php',
'xhpast_get_build_instructions' => 'parser/xhpast/bin/xhpast_parse.php',
Index: src/channel/PhutilChannel.php
===================================================================
--- src/channel/PhutilChannel.php
+++ src/channel/PhutilChannel.php
@@ -231,6 +231,14 @@
/**
+ * Close the channel for writing.
+ *
+ * @return this
+ * @task impl
+ */
+ abstract public function closeWriteChannel();
+
+ /**
* Test if the channel is open for reading.
*
* @return bool True if the channel is open for reading.
Index: src/channel/PhutilChannelChannel.php
===================================================================
--- src/channel/PhutilChannelChannel.php
+++ src/channel/PhutilChannelChannel.php
@@ -40,6 +40,10 @@
return $this->channel->isOpen();
}
+ public function closeWriteChannel() {
+ return $this->channel->closeWriteChannel();
+ }
+
public function isOpenForReading() {
return $this->channel->isOpenForReading();
}
Index: src/channel/PhutilExecChannel.php
===================================================================
--- src/channel/PhutilExecChannel.php
+++ src/channel/PhutilExecChannel.php
@@ -108,6 +108,10 @@
$this->future->write($bytes, $keep_pipe = true);
}
+ public function closeWriteChannel() {
+ $this->future->write('', $keep_pipe = false);
+ }
+
protected function writeBytes($bytes) {
throw new Exception("ExecFuture can not write bytes directly!");
}
Index: src/channel/PhutilSocketChannel.php
===================================================================
--- src/channel/PhutilSocketChannel.php
+++ src/channel/PhutilSocketChannel.php
@@ -173,6 +173,10 @@
}
}
+ public function closeWriteChannel() {
+ $this->closeWriteSocket();
+ }
+
private function closeOneSocket($socket) {
if (!$socket) {
return;
Index: src/channel/__tests__/PhutilPHPObjectProtocolChannelTestCase.php
===================================================================
--- src/channel/__tests__/PhutilPHPObjectProtocolChannelTestCase.php
+++ src/channel/__tests__/PhutilPHPObjectProtocolChannelTestCase.php
@@ -26,4 +26,41 @@
"Objects are not the same.");
}
+ public function testCloseSocketWriteChannel() {
+ list($x, $y) = PhutilSocketChannel::newChannelPair();
+ $xp = new PhutilPHPObjectProtocolChannel($x);
+ $yp = new PhutilPHPObjectProtocolChannel($y);
+
+ $yp->closeWriteChannel();
+ $yp->update();
+
+ // NOTE: This test is more broad than the implementation needs to be. A
+ // better test would be to verify that this throws an exception:
+ //
+ // $xp->waitForMessage();
+ //
+ // However, if the test breaks, that method will hang forever instead of
+ // returning, which would be hard to diagnose. Since the current
+ // implementation shuts down the entire channel, just test for that.
+
+ $this->assertEqual(false, $xp->update(), 'Expected channel to close.');
+ }
+
+ public function testCloseExecWriteChannel() {
+ $future = new ExecFuture('cat');
+
+ // If this test breaks, we want to explode, not hang forever.
+ $future->setTimeout(5);
+
+ $exec_channel = new PhutilExecChannel($future);
+ $exec_channel->write("quack");
+ $exec_channel->closeWriteChannel();
+
+ // If `closeWriteChannel()` did what it is supposed to, this will just
+ // echo "quack" and exit with no error code. If the channel did not close,
+ // this will time out after 5 seconds and throw.
+ $future->resolvex();
+ }
+
+
}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 4:07 AM (2 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7712514
Default Alt Text
D7552.id17041.diff (4 KB)

Event Timeline