io/async/EventBase.h \
io/async/EventBaseLocal.h \
io/async/EventBaseManager.h \
+ io/async/EventBaseThread.h \
io/async/EventFDWrapper.h \
io/async/EventHandler.h \
io/async/EventUtil.h \
io/async/EventBase.cpp \
io/async/EventBaseLocal.cpp \
io/async/EventBaseManager.cpp \
+ io/async/EventBaseThread.cpp \
io/async/EventHandler.cpp \
io/async/Request.cpp \
io/async/SSLContext.cpp \
--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <folly/io/async/EventBaseThread.h>
+
+#include <folly/Memory.h>
+#include <folly/io/async/ScopedEventBaseThread.h>
+
+namespace folly {
+
+EventBaseThread::EventBaseThread() : EventBaseThread(true) {}
+
+EventBaseThread::EventBaseThread(bool autostart, EventBaseManager* ebm)
+ : ebm_(ebm) {
+ if (autostart) {
+ start();
+ }
+}
+
+EventBaseThread::EventBaseThread(EventBaseManager* ebm)
+ : EventBaseThread(true, ebm) {}
+
+EventBaseThread::~EventBaseThread() = default;
+
+EventBaseThread::EventBaseThread(EventBaseThread&&) noexcept = default;
+EventBaseThread& EventBaseThread::operator=(EventBaseThread&&) noexcept =
+ default;
+
+EventBase* EventBaseThread::getEventBase() const {
+ return th_ ? th_->getEventBase() : nullptr;
+}
+
+bool EventBaseThread::running() const {
+ return !!th_;
+}
+
+void EventBaseThread::start() {
+ if (th_) {
+ return;
+ }
+ th_ = make_unique<ScopedEventBaseThread>(ebm_);
+}
+
+void EventBaseThread::stop() {
+ th_ = nullptr;
+}
+}
--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace folly {
+
+class EventBase;
+class EventBaseManager;
+class ScopedEventBaseThread;
+
+class EventBaseThread {
+ public:
+ EventBaseThread();
+ explicit EventBaseThread(bool autostart, EventBaseManager* ebm = nullptr);
+ explicit EventBaseThread(EventBaseManager* ebm);
+ ~EventBaseThread();
+
+ EventBaseThread(EventBaseThread&&) noexcept;
+ EventBaseThread& operator=(EventBaseThread&&) noexcept;
+
+ EventBase* getEventBase() const;
+
+ bool running() const;
+ void start();
+ void stop();
+
+ private:
+ EventBaseThread(EventBaseThread const&) = default;
+ EventBaseThread& operator=(EventBaseThread const&) = default;
+
+ EventBaseManager* ebm_;
+ std::unique_ptr<ScopedEventBaseThread> th_;
+};
+}
#include <folly/io/async/ScopedEventBaseThread.h>
#include <thread>
+
#include <folly/Memory.h>
+#include <folly/io/async/EventBaseManager.h>
using namespace std;
static void run(EventBaseManager* ebm, EventBase* eb) {
ebm->setEventBase(eb, false);
- CHECK_NOTNULL(eb)->loopForever();
+ eb->loopForever();
ebm->clearEventBase();
}
-ScopedEventBaseThread::ScopedEventBaseThread(
- bool autostart,
- EventBaseManager* ebm)
+ScopedEventBaseThread::ScopedEventBaseThread()
+ : ScopedEventBaseThread(nullptr) {}
+
+ScopedEventBaseThread::ScopedEventBaseThread(EventBaseManager* ebm)
: ebm_(ebm ? ebm : EventBaseManager::get()) {
- if (autostart) {
- start();
- }
+ th_ = thread(run, ebm_, &eb_);
+ eb_.waitUntilRunning();
}
-ScopedEventBaseThread::ScopedEventBaseThread(
- EventBaseManager* ebm) :
- ScopedEventBaseThread(true, ebm) {}
-
ScopedEventBaseThread::~ScopedEventBaseThread() {
- stop();
-}
-
-ScopedEventBaseThread::ScopedEventBaseThread(
- ScopedEventBaseThread&& /* other */) noexcept = default;
-
-ScopedEventBaseThread& ScopedEventBaseThread::operator=(
- ScopedEventBaseThread&& /* other */) noexcept = default;
-
-void ScopedEventBaseThread::start() {
- if (running()) {
- return;
- }
- eventBase_ = make_unique<EventBase>();
- thread_ = make_unique<thread>(run, ebm_, eventBase_.get());
- eventBase_->waitUntilRunning();
-}
-
-void ScopedEventBaseThread::stop() {
- if (!running()) {
- return;
- }
- eventBase_->terminateLoopSoon();
- thread_->join();
- eventBase_ = nullptr;
- thread_ = nullptr;
-}
-
-bool ScopedEventBaseThread::running() {
- CHECK(bool(eventBase_) == bool(thread_));
- return eventBase_ && thread_;
+ eb_.terminateLoopSoon();
+ th_.join();
}
}
#include <memory>
#include <thread>
#include <folly/io/async/EventBase.h>
-#include <folly/io/async/EventBaseManager.h>
namespace folly {
+class EventBaseManager;
+
/**
* A helper class to start a new thread running a EventBase loop.
*
*/
class ScopedEventBaseThread {
public:
- explicit ScopedEventBaseThread(
- bool autostart = true,
- EventBaseManager* ebm = nullptr);
- explicit ScopedEventBaseThread(
- EventBaseManager* ebm);
+ ScopedEventBaseThread();
+ explicit ScopedEventBaseThread(EventBaseManager* ebm);
~ScopedEventBaseThread();
- ScopedEventBaseThread(ScopedEventBaseThread&& other) noexcept;
- ScopedEventBaseThread &operator=(ScopedEventBaseThread&& other) noexcept;
-
- /**
- * Get a pointer to the EventBase driving this thread.
- */
EventBase* getEventBase() const {
- return eventBase_.get();
+ return &eb_;
}
- void start();
- void stop();
- bool running();
-
private:
+ ScopedEventBaseThread(ScopedEventBaseThread&& other) = delete;
+ ScopedEventBaseThread& operator=(ScopedEventBaseThread&& other) = delete;
+
ScopedEventBaseThread(const ScopedEventBaseThread& other) = delete;
ScopedEventBaseThread& operator=(const ScopedEventBaseThread& other) = delete;
EventBaseManager* ebm_;
- std::unique_ptr<EventBase> eventBase_;
- std::unique_ptr<std::thread> thread_;
+ mutable EventBase eb_;
+ std::thread th_;
};
}
--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <folly/io/async/EventBaseThread.h>
+
+#include <chrono>
+
+#include <folly/Baton.h>
+#include <folly/io/async/EventBaseManager.h>
+#include <folly/portability/GTest.h>
+
+using namespace std;
+using namespace std::chrono;
+using namespace folly;
+
+class EventBaseThreadTest : public testing::Test {};
+
+TEST_F(EventBaseThreadTest, example) {
+ EventBaseThread ebt;
+
+ Baton<> done;
+ ebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
+ ASSERT_TRUE(done.timed_wait(seconds(1)));
+}
+
+TEST_F(EventBaseThreadTest, start_stop) {
+ EventBaseThread ebt(false);
+
+ for (size_t i = 0; i < 4; ++i) {
+ EXPECT_EQ(nullptr, ebt.getEventBase());
+ ebt.start();
+ EXPECT_NE(nullptr, ebt.getEventBase());
+
+ Baton<> done;
+ ebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
+ ASSERT_TRUE(done.timed_wait(seconds(1)));
+
+ EXPECT_NE(nullptr, ebt.getEventBase());
+ ebt.stop();
+ EXPECT_EQ(nullptr, ebt.getEventBase());
+ }
+}
+
+TEST_F(EventBaseThreadTest, move) {
+ auto ebt0 = EventBaseThread();
+ auto ebt1 = std::move(ebt0);
+ auto ebt2 = std::move(ebt1);
+
+ EXPECT_EQ(nullptr, ebt0.getEventBase());
+ EXPECT_EQ(nullptr, ebt1.getEventBase());
+ EXPECT_NE(nullptr, ebt2.getEventBase());
+
+ Baton<> done;
+ ebt2.getEventBase()->runInEventBaseThread([&] { done.post(); });
+ ASSERT_TRUE(done.timed_wait(seconds(1)));
+}
+
+TEST_F(EventBaseThreadTest, self_move) {
+ EventBaseThread ebt0;
+ auto ebt = std::move(ebt0);
+
+ EXPECT_NE(nullptr, ebt.getEventBase());
+
+ Baton<> done;
+ ebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
+ ASSERT_TRUE(done.timed_wait(seconds(1)));
+}
+
+TEST_F(EventBaseThreadTest, default_manager) {
+ auto ebm = EventBaseManager::get();
+ EventBaseThread ebt;
+ auto ebt_eb = ebt.getEventBase();
+ auto ebm_eb = static_cast<EventBase*>(nullptr);
+ ebt_eb->runInEventBaseThreadAndWait([&] { ebm_eb = ebm->getEventBase(); });
+ EXPECT_EQ(uintptr_t(ebt_eb), uintptr_t(ebm_eb));
+}
+
+TEST_F(EventBaseThreadTest, custom_manager) {
+ EventBaseManager ebm;
+ EventBaseThread ebt(&ebm);
+ auto ebt_eb = ebt.getEventBase();
+ auto ebm_eb = static_cast<EventBase*>(nullptr);
+ ebt_eb->runInEventBaseThreadAndWait([&] { ebm_eb = ebm.getEventBase(); });
+ EXPECT_EQ(uintptr_t(ebt_eb), uintptr_t(ebm_eb));
+}
#include <folly/io/async/ScopedEventBaseThread.h>
#include <chrono>
+
#include <folly/Baton.h>
+#include <folly/io/async/EventBaseManager.h>
#include <folly/portability/GTest.h>
using namespace std;
ASSERT_TRUE(done.timed_wait(seconds(1)));
}
-TEST_F(ScopedEventBaseThreadTest, start_stop) {
- ScopedEventBaseThread sebt(false);
-
- for (size_t i = 0; i < 4; ++i) {
- EXPECT_EQ(nullptr, sebt.getEventBase());
- sebt.start();
- EXPECT_NE(nullptr, sebt.getEventBase());
-
- Baton<> done;
- sebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
- ASSERT_TRUE(done.timed_wait(seconds(1)));
-
- EXPECT_NE(nullptr, sebt.getEventBase());
- sebt.stop();
- EXPECT_EQ(nullptr, sebt.getEventBase());
- }
-}
-
-TEST_F(ScopedEventBaseThreadTest, move) {
- auto sebt0 = ScopedEventBaseThread();
- auto sebt1 = std::move(sebt0);
- auto sebt2 = std::move(sebt1);
-
- EXPECT_EQ(nullptr, sebt0.getEventBase());
- EXPECT_EQ(nullptr, sebt1.getEventBase());
- EXPECT_NE(nullptr, sebt2.getEventBase());
-
- Baton<> done;
- sebt2.getEventBase()->runInEventBaseThread([&] { done.post(); });
- ASSERT_TRUE(done.timed_wait(seconds(1)));
-}
-
-TEST_F(ScopedEventBaseThreadTest, self_move) {
- ScopedEventBaseThread sebt0;
- auto sebt = std::move(sebt0);
-
- EXPECT_NE(nullptr, sebt.getEventBase());
-
- Baton<> done;
- sebt.getEventBase()->runInEventBaseThread([&] { done.post(); });
- ASSERT_TRUE(done.timed_wait(seconds(1)));
-}
-
TEST_F(ScopedEventBaseThreadTest, default_manager) {
auto ebm = EventBaseManager::get();
ScopedEventBaseThread sebt;