Commit 46475bd7 authored by Kenton Varda's avatar Kenton Varda

Actually call setRunnable() as documented.

parent a81ce929
...@@ -506,5 +506,62 @@ TEST(Async, Daemonize) { ...@@ -506,5 +506,62 @@ TEST(Async, Daemonize) {
EXPECT_TRUE(ran3); EXPECT_TRUE(ran3);
} }
class DummyEventPort: public EventPort {
public:
bool runnable = false;
int callCount = 0;
void wait() override { KJ_FAIL_ASSERT("Nothing to wait for."); }
void poll() override {}
void setRunnable(bool runnable) {
this->runnable = runnable;
++callCount;
}
};
TEST(Async, SetRunnable) {
DummyEventPort port;
EventLoop loop(port);
EXPECT_FALSE(port.runnable);
EXPECT_EQ(0, port.callCount);
{
auto promise = evalLater([]() {});
promise.eagerlyEvaluate();
EXPECT_TRUE(port.runnable);
loop.run(1);
EXPECT_FALSE(port.runnable);
EXPECT_EQ(2, port.callCount);
promise.wait();
EXPECT_FALSE(port.runnable);
EXPECT_EQ(4, port.callCount);
}
{
auto paf = newPromiseAndFulfiller<void>();
auto promise = paf.promise.then([]() {});
promise.eagerlyEvaluate();
EXPECT_FALSE(port.runnable);
auto promise2 = evalLater([]() {});
promise2.eagerlyEvaluate();
paf.fulfiller->fulfill();
EXPECT_TRUE(port.runnable);
loop.run(1);
EXPECT_TRUE(port.runnable);
loop.run(10);
EXPECT_FALSE(port.runnable);
promise.wait();
EXPECT_FALSE(port.runnable);
EXPECT_EQ(8, port.callCount);
}
}
} // namespace } // namespace
} // namespace kj } // namespace kj
...@@ -245,6 +245,8 @@ void EventLoop::run(uint maxTurnCount) { ...@@ -245,6 +245,8 @@ void EventLoop::run(uint maxTurnCount) {
break; break;
} }
} }
setRunnable(head != nullptr);
} }
bool EventLoop::turn() { bool EventLoop::turn() {
...@@ -279,6 +281,13 @@ bool EventLoop::turn() { ...@@ -279,6 +281,13 @@ bool EventLoop::turn() {
} }
} }
void EventLoop::setRunnable(bool runnable) {
if (runnable != lastRunnableState) {
port.setRunnable(runnable);
lastRunnableState = runnable;
}
}
namespace _ { // private namespace _ { // private
void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result) { void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result) {
...@@ -298,6 +307,8 @@ void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result) { ...@@ -298,6 +307,8 @@ void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result) {
} }
} }
loop.setRunnable(loop.head != nullptr);
node->get(result); node->get(result);
KJ_IF_MAYBE(exception, kj::runCatchingExceptions([&]() { KJ_IF_MAYBE(exception, kj::runCatchingExceptions([&]() {
node = nullptr; node = nullptr;
...@@ -357,6 +368,8 @@ void Event::armDepthFirst() { ...@@ -357,6 +368,8 @@ void Event::armDepthFirst() {
if (loop.tail == prev) { if (loop.tail == prev) {
loop.tail = &next; loop.tail = &next;
} }
loop.setRunnable(true);
} }
} }
...@@ -374,6 +387,8 @@ void Event::armBreadthFirst() { ...@@ -374,6 +387,8 @@ void Event::armBreadthFirst() {
} }
loop.tail = &next; loop.tail = &next;
loop.setRunnable(true);
} }
} }
......
...@@ -567,6 +567,9 @@ private: ...@@ -567,6 +567,9 @@ private:
bool running = false; bool running = false;
// True while looping -- wait() is then not allowed. // True while looping -- wait() is then not allowed.
bool lastRunnableState = false;
// What did we last pass to port.setRunnable()?
_::Event* head = nullptr; _::Event* head = nullptr;
_::Event** tail = &head; _::Event** tail = &head;
_::Event** depthFirstInsertPoint = &head; _::Event** depthFirstInsertPoint = &head;
...@@ -574,6 +577,7 @@ private: ...@@ -574,6 +577,7 @@ private:
Own<_::TaskSetImpl> daemons; Own<_::TaskSetImpl> daemons;
bool turn(); bool turn();
void setRunnable(bool runnable);
friend void _::daemonize(kj::Promise<void>&& promise); friend void _::daemonize(kj::Promise<void>&& promise);
friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result); friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result);
......
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