From c2132bba2689552bfd6e07eb70f36bc91ddb43ef Mon Sep 17 00:00:00 2001
From: James Sedgwick <jsedgwick@fb.com>
Date: Wed, 10 Dec 2014 19:23:24 -0800
Subject: [PATCH] future_* callbacks in ThreadManager thread

Summary:
This is a squashed diff consisting of the following approved diffs

D1714007
D1714645
D1715686
D1719963
D1720725
D1721838
D1721856
D1721920
D1721956
D1724910
D1728289

- execute future_* handlers in TM thread
- call async thrift clients from any thread, not just EB thread
- store a request's EventBase in the RequestContext for easier client management
* this last one will change in favor of using a global IO executor but this should still land as an intermediate step. See D1727894

Test Plan: see component diff test plans. otherwise, contbuild.

Reviewed By: davejwatson@fb.com

Subscribers: trunkagent, ruibalp, targeting-diff-backend@, hannesr, alandau, prometheus-diffs@, jeremyfein, mshneer, folly-diffs@, bmatheny, tingy

FB internal diff: D1732289

Tasks: 5003045, 5645785

Signature: t1:1732289:1418253508:30b724a91717cf7fe21029e0a1eaf239db1650be
---
 folly/io/async/EventBase.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/folly/io/async/EventBase.h b/folly/io/async/EventBase.h
index 92de83fc..ec4a6ad6 100644
--- a/folly/io/async/EventBase.h
+++ b/folly/io/async/EventBase.h
@@ -19,6 +19,7 @@
 #include <glog/logging.h>
 #include <folly/io/async/AsyncTimeout.h>
 #include <folly/io/async/TimeoutManager.h>
+#include <folly/io/async/Request.h>
 #include <folly/wangle/Executor.h>
 #include <memory>
 #include <stack>
@@ -51,6 +52,31 @@ class EventBaseObserver {
     int64_t busyTime, int64_t idleTime) = 0;
 };
 
+// Helper class that sets and retrieves the EventBase associated with a given
+// request via RequestContext. See Request.h for that mechanism.
+class RequestEventBase : public RequestData {
+ public:
+  static EventBase* get() {
+    auto data = dynamic_cast<RequestEventBase*>(
+        RequestContext::get()->getContextData(kContextDataName));
+    if (!data) {
+      return nullptr;
+    }
+    return data->eb_;
+  }
+
+  static void set(EventBase* eb) {
+    RequestContext::get()->setContextData(
+        kContextDataName,
+        std::unique_ptr<RequestEventBase>(new RequestEventBase(eb)));
+  }
+
+ private:
+  explicit RequestEventBase(EventBase* eb) : eb_(eb) {}
+  EventBase* eb_;
+  static constexpr const char* kContextDataName{"EventBase"};
+};
+
 /**
  * This class is a wrapper for all asynchronous I/O processing functionality
  *
-- 
2.34.1