Commit dd1ecd8c authored by Kenton Varda's avatar Kenton Varda

Fix whenWriteDisconnected() on poll()-based UnixEventPort.

While working on this PR, I noticed that http-socketpair-test was failing when using the poll()-based UnixEventPort. This fixes that. This is tangential to the PR, though.
parent 85b67d42
...@@ -775,6 +775,46 @@ TEST(AsyncUnixTest, ChildProcess) { ...@@ -775,6 +775,46 @@ TEST(AsyncUnixTest, ChildProcess) {
// child3 will be killed and synchronously waited on the way out. // child3 will be killed and synchronously waited on the way out.
} }
KJ_TEST("UnixEventPort whenWriteDisconnected()") {
captureSignals();
UnixEventPort port;
EventLoop loop(port);
WaitScope waitScope(loop);
int fds_[2];
KJ_SYSCALL(socketpair(AF_UNIX, SOCK_STREAM, 0, fds_));
kj::AutoCloseFd fds[2] = { kj::AutoCloseFd(fds_[0]), kj::AutoCloseFd(fds_[1]) };
UnixEventPort::FdObserver observer(port, fds[0], UnixEventPort::FdObserver::OBSERVE_READ);
// At one point, the poll()-based version of UnixEventPort had a bug where if some other event
// had completed previously, whenWriteDisconnected() would stop being watched for. So we watch
// for readability as well and check that that goes away first.
auto readablePromise = observer.whenBecomesReadable();
auto hupPromise = observer.whenWriteDisconnected();
KJ_EXPECT(!readablePromise.poll(waitScope));
KJ_EXPECT(!hupPromise.poll(waitScope));
KJ_SYSCALL(write(fds[1], "foo", 3));
KJ_ASSERT(readablePromise.poll(waitScope));
readablePromise.wait(waitScope);
{
char junk[16];
ssize_t n;
KJ_SYSCALL(n = read(fds[0], junk, 16));
KJ_EXPECT(n == 3);
}
KJ_EXPECT(!hupPromise.poll(waitScope));
fds[1] = nullptr;
KJ_ASSERT(hupPromise.poll(waitScope));
hupPromise.wait(waitScope);
}
} // namespace } // namespace
} // namespace kj } // namespace kj
......
...@@ -681,7 +681,8 @@ void UnixEventPort::FdObserver::fire(short events) { ...@@ -681,7 +681,8 @@ void UnixEventPort::FdObserver::fire(short events) {
} }
} }
if (readFulfiller == nullptr && writeFulfiller == nullptr && urgentFulfiller == nullptr) { if (readFulfiller == nullptr && writeFulfiller == nullptr && urgentFulfiller == nullptr &&
hupFulfiller == nullptr) {
// Remove from list. // Remove from list.
if (next == nullptr) { if (next == nullptr) {
eventPort.observersTail = prev; eventPort.observersTail = prev;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment