From: Yedidya Feldblum Date: Sat, 7 Oct 2017 01:04:56 +0000 (-0700) Subject: Let EventBase::runInEventBaseThreadAndWait consume its argument X-Git-Tag: v2017.10.09.00~1 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=662b86a949f85dfcbf966a346dba8306710eabcb;p=folly.git 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 --- diff --git a/folly/io/async/EventBase.cpp b/folly/io/async/EventBase.cpp index 7ef3c8a3..56f92c8d 100644 --- a/folly/io/async/EventBase.cpp +++ b/folly/io/async/EventBase.cpp @@ -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; diff --git a/folly/io/async/EventBase.h b/folly/io/async/EventBase.h index fff75adb..ee7ceca7 100644 --- a/folly/io/async/EventBase.h +++ b/folly/io/async/EventBase.h @@ -127,7 +127,6 @@ class EventBase : private boost::noncopyable, public DrivableExecutor { public: using Func = folly::Function; - using FuncRef = folly::FunctionRef; /** * 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