ScopedEventBaseThread should support an EventBaseManager context.
authorYedidya Feldblum <yfeldblum@fb.com>
Wed, 5 Aug 2015 21:44:14 +0000 (14:44 -0700)
committerfacebook-github-bot-9 <folly-bot@fb.com>
Wed, 5 Aug 2015 22:22:13 +0000 (15:22 -0700)
Summary: [Folly] ScopedEventBaseThread should support an EventBaseManager context.

Reviewed By: @Gownta

Differential Revision: D2314049

folly/io/async/ScopedEventBaseThread.cpp
folly/io/async/ScopedEventBaseThread.h
folly/io/async/test/ScopedEventBaseThreadTest.cpp

index 29a44592729f55289b6bf95c8243888bf84a38a7..7821d17baf34495fdc242f8fcf4111396341a81b 100644 (file)
@@ -23,12 +23,29 @@ using namespace std;
 
 namespace folly {
 
-ScopedEventBaseThread::ScopedEventBaseThread(bool autostart) {
+static void run(EventBaseManager* ebm, EventBase* eb) {
+  if (ebm) {
+    ebm->setEventBase(eb, false);
+  }
+  CHECK_NOTNULL(eb)->loopForever();
+  if (ebm) {
+    ebm->clearEventBase();
+  }
+}
+
+ScopedEventBaseThread::ScopedEventBaseThread(
+    bool autostart,
+    EventBaseManager* ebm) :
+  ebm_(ebm) {
   if (autostart) {
     start();
   }
 }
 
+ScopedEventBaseThread::ScopedEventBaseThread(
+    EventBaseManager* ebm) :
+  ScopedEventBaseThread(true, ebm) {}
+
 ScopedEventBaseThread::~ScopedEventBaseThread() {
   stop();
 }
@@ -44,7 +61,7 @@ void ScopedEventBaseThread::start() {
     return;
   }
   eventBase_ = make_unique<EventBase>();
-  thread_ = make_unique<thread>(&EventBase::loopForever, &*eventBase_);
+  thread_ = make_unique<thread>(run, ebm_, eventBase_.get());
   eventBase_->waitUntilRunning();
 }
 
index fa35f35fbe45c72e34ce535eda08522cbd235c5d..e500aefc9c81fd96c0c4f81acfd64f121d434117 100644 (file)
 #include <memory>
 #include <thread>
 #include <folly/io/async/EventBase.h>
+#include <folly/io/async/EventBaseManager.h>
 
 namespace folly {
 
 /**
- * A helper class to start a new thread running a TEventBase loop.
+ * A helper class to start a new thread running a EventBase loop.
  *
  * The new thread will be started by the ScopedEventBaseThread constructor.
  * When the ScopedEventBaseThread object is destroyed, the thread will be
@@ -31,14 +32,18 @@ namespace folly {
  */
 class ScopedEventBaseThread {
  public:
-  explicit ScopedEventBaseThread(bool autostart = true);
+  explicit ScopedEventBaseThread(
+      bool autostart = true,
+      EventBaseManager* ebm = nullptr);
+  explicit ScopedEventBaseThread(
+      EventBaseManager* ebm);
   ~ScopedEventBaseThread();
 
   ScopedEventBaseThread(ScopedEventBaseThread&& other) noexcept;
   ScopedEventBaseThread &operator=(ScopedEventBaseThread&& other) noexcept;
 
   /**
-   * Get a pointer to the TEventBase driving this thread.
+   * Get a pointer to the EventBase driving this thread.
    */
   EventBase* getEventBase() const {
     return eventBase_.get();
@@ -52,6 +57,7 @@ class ScopedEventBaseThread {
   ScopedEventBaseThread(const ScopedEventBaseThread& other) = delete;
   ScopedEventBaseThread& operator=(const ScopedEventBaseThread& other) = delete;
 
+  EventBaseManager* ebm_;
   std::unique_ptr<EventBase> eventBase_;
   std::unique_ptr<std::thread> thread_;
 };
index b6373070089baf24cf5268ec582cd3fcc8e20d25..b102dd58466143e59fc69b25191d23157d21c729 100644 (file)
@@ -77,3 +77,14 @@ TEST_F(ScopedEventBaseThreadTest, self_move) {
   sebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
   done.timed_wait(steady_clock::now() + milliseconds(100));
 }
+
+TEST_F(ScopedEventBaseThreadTest, manager) {
+  EventBaseManager ebm;
+  ScopedEventBaseThread sebt(&ebm);
+  auto sebt_eb = sebt.getEventBase();
+  auto ebm_eb = (EventBase*)nullptr;
+  sebt_eb->runInEventBaseThreadAndWait([&] {
+      ebm_eb = ebm.getEventBase();
+  });
+  EXPECT_EQ(uintptr_t(sebt_eb), uintptr_t(ebm_eb));
+}