Support naming a ScopedEventBaseThread
authorChristopher Dykes <cdykes@fb.com>
Thu, 4 May 2017 23:46:53 +0000 (16:46 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 4 May 2017 23:51:00 +0000 (16:51 -0700)
Summary:
The setThreadName API is in the process of being changed to not accept a thread id, which means the thread itself needs to set the name.
There are times where a `ScopedEventBaseThread` needs to be named, and this makes that possible.

Reviewed By: yfeldblum

Differential Revision: D4916781

fbshipit-source-id: dab05b520a715183ce069151ed16864fa1331abc

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

index 25f0cba..9f14b91 100644 (file)
 #include <thread>
 
 #include <folly/Function.h>
+#include <folly/Range.h>
+#include <folly/ThreadName.h>
 #include <folly/io/async/EventBaseManager.h>
 
 using namespace std;
 
 namespace folly {
 
-static void run(EventBaseManager* ebm, EventBase* eb) {
+static void run(EventBaseManager* ebm, EventBase* eb, const StringPiece& name) {
+  if (name.size()) {
+    folly::setThreadName(name);
+  }
+
   ebm->setEventBase(eb, false);
   eb->loopForever();
 
@@ -36,12 +42,20 @@ static void run(EventBaseManager* ebm, EventBase* eb) {
 }
 
 ScopedEventBaseThread::ScopedEventBaseThread()
-    : ScopedEventBaseThread(nullptr) {}
+    : ScopedEventBaseThread(nullptr, "") {}
+
+ScopedEventBaseThread::ScopedEventBaseThread(const StringPiece& name)
+    : ScopedEventBaseThread(nullptr, name) {}
 
 ScopedEventBaseThread::ScopedEventBaseThread(EventBaseManager* ebm)
+    : ScopedEventBaseThread(ebm, "") {}
+
+ScopedEventBaseThread::ScopedEventBaseThread(
+    EventBaseManager* ebm,
+    const StringPiece& name)
     : ebm_(ebm ? ebm : EventBaseManager::get()) {
   new (&eb_) EventBase();
-  th_ = thread(run, ebm_, &eb_);
+  th_ = thread(run, ebm_, &eb_, name);
   eb_.waitUntilRunning();
 }
 
index 52824cd..0a8775c 100644 (file)
@@ -24,6 +24,9 @@
 namespace folly {
 
 class EventBaseManager;
+template <class Iter>
+class Range;
+typedef Range<const char*> StringPiece;
 
 /**
  * A helper class to start a new thread running a EventBase loop.
@@ -35,7 +38,11 @@ class EventBaseManager;
 class ScopedEventBaseThread {
  public:
   ScopedEventBaseThread();
+  explicit ScopedEventBaseThread(const StringPiece& name);
   explicit ScopedEventBaseThread(EventBaseManager* ebm);
+  explicit ScopedEventBaseThread(
+      EventBaseManager* ebm,
+      const StringPiece& name);
   ~ScopedEventBaseThread();
 
   EventBase* getEventBase() const {
index 02fd24d..79dbe6f 100644 (file)
 #include <folly/io/async/ScopedEventBaseThread.h>
 
 #include <chrono>
+#include <string>
 
 #include <folly/Baton.h>
 #include <folly/Optional.h>
+#include <folly/ThreadName.h>
 #include <folly/io/async/EventBaseManager.h>
 #include <folly/portability/GTest.h>
 
@@ -37,6 +39,24 @@ TEST_F(ScopedEventBaseThreadTest, example) {
   ASSERT_TRUE(done.timed_wait(seconds(1)));
 }
 
+TEST_F(ScopedEventBaseThreadTest, named_example) {
+  static constexpr StringPiece kThreadName{"named_example"};
+
+  Optional<std::string> createdThreadName;
+  Baton<> done;
+
+  ScopedEventBaseThread sebt{kThreadName};
+  sebt.getEventBase()->runInEventBaseThread([&] {
+    createdThreadName = folly::getCurrentThreadName();
+    done.post();
+  });
+
+  ASSERT_TRUE(done.timed_wait(seconds(1)));
+  if (createdThreadName) {
+    ASSERT_EQ(kThreadName.toString(), createdThreadName.value());
+  }
+}
+
 TEST_F(ScopedEventBaseThreadTest, default_manager) {
   auto ebm = EventBaseManager::get();
   ScopedEventBaseThread sebt;