Commit 662b86a9 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Let EventBase::runInEventBaseThreadAndWait consume its argument

Summary:
[Folly] Let `EventBase::runInEventBaseThreadAndWait` consume its argument.

Likewise `EventBase::runImmediatelyOrRunInEventBaseThreadAndWait`.

And enforce that the function is destructed before returning, so that, in the case of a wrapped lambda, all captured objects' destructors run before returning from the function.

Reviewed By: elsteveogrande

Differential Revision: D5994106

fbshipit-source-id: 816c9431a85a3d41e4fda321065614f4c18f0697
parent 05ced584
......@@ -566,7 +566,7 @@ bool EventBase::runInEventBaseThread(Func fn) {
return true;
}
bool EventBase::runInEventBaseThreadAndWait(FuncRef fn) {
bool EventBase::runInEventBaseThreadAndWait(Func fn) {
if (inRunningEventBaseThread()) {
LOG(ERROR) << "EventBase " << this << ": Waiting in the event loop is not "
<< "allowed";
......@@ -574,18 +574,20 @@ bool EventBase::runInEventBaseThreadAndWait(FuncRef fn) {
}
Baton<> ready;
runInEventBaseThread([&] {
runInEventBaseThread([&ready, fn = std::move(fn)]() mutable {
SCOPE_EXIT {
ready.post();
};
fn();
// A trick to force the stored functor to be executed and then destructed
// before posting the baton and waking the waiting thread.
copy(std::move(fn))();
});
ready.wait();
return true;
}
bool EventBase::runImmediatelyOrRunInEventBaseThreadAndWait(FuncRef fn) {
bool EventBase::runImmediatelyOrRunInEventBaseThreadAndWait(Func fn) {
if (isInEventBaseThread()) {
fn();
return true;
......
......@@ -127,7 +127,6 @@ class EventBase : private boost::noncopyable,
public DrivableExecutor {
public:
using Func = folly::Function<void()>;
using FuncRef = folly::FunctionRef<void()>;
/**
* A callback interface to use with runInLoop()
......@@ -417,7 +416,7 @@ class EventBase : private boost::noncopyable,
* Like runInEventBaseThread, but the caller waits for the callback to be
* executed.
*/
bool runInEventBaseThreadAndWait(FuncRef fn);
bool runInEventBaseThreadAndWait(Func fn);
/*
* Like runInEventBaseThreadAndWait, except if the caller is already in the
......@@ -430,7 +429,7 @@ class EventBase : private boost::noncopyable,
* Like runInEventBaseThreadAndWait, except if the caller is already in the
* event base thread, the functor is simply run inline.
*/
bool runImmediatelyOrRunInEventBaseThreadAndWait(FuncRef fn);
bool runImmediatelyOrRunInEventBaseThreadAndWait(Func fn);
/**
* Set the maximum desired latency in us and provide a callback which will be
......
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