Commit 84e83ecc authored by Dave Watson's avatar Dave Watson

Clean up RequestContext

Summary: Using a ThreadLocal cleans up the code quite a bit.  Also reuse the shared_ptr in create instead of creating a new one saves an allocation

Test Plan:
fbconfig thrift/lib/cpp/test:RequestContextTest; fbmake runtests

fbconfig common/services/cpp/test:trace_test; fbmake runtests

Reviewed By: hans@fb.com

Subscribers: trunkagent, doug, alandau, bmatheny, njormrod, mshneer, folly-diffs@, vloh

FB internal diff: D1663960

Signature: t1:1663960:1415390250:36d9b772016d2a12d804e98edbc1725af882e507
parent fc7801ad
...@@ -65,26 +65,22 @@ class RequestContext { ...@@ -65,26 +65,22 @@ class RequestContext {
// Create a unique requext context for this request. // Create a unique requext context for this request.
// It will be passed between queues / threads (where implemented), // It will be passed between queues / threads (where implemented),
// so it should be valid for the lifetime of the request. // so it should be valid for the lifetime of the request.
static bool create() { static void create() {
if(!FLAGS_enable_request_context) { if(!FLAGS_enable_request_context) {
return false; return;
} }
bool prev = getStaticContext().get() != nullptr; getStaticContext() = std::make_shared<RequestContext>();
getStaticContext().reset(new std::shared_ptr<RequestContext>(
std::make_shared<RequestContext>()));
return prev;
} }
// Get the current context. // Get the current context.
static RequestContext* get() { static RequestContext* get() {
if (!FLAGS_enable_request_context || if (getStaticContext() == nullptr) {
getStaticContext().get() == nullptr) {
if (defaultContext == nullptr) { if (defaultContext == nullptr) {
defaultContext = new RequestContext; defaultContext = new RequestContext;
} }
return defaultContext; return defaultContext;
} }
return getStaticContext().get()->get(); return getStaticContext().get();
} }
// The following API may be used to set per-request data in a thread-safe way. // The following API may be used to set per-request data in a thread-safe way.
...@@ -138,28 +134,17 @@ class RequestContext { ...@@ -138,28 +134,17 @@ class RequestContext {
setContext(std::shared_ptr<RequestContext> ctx) { setContext(std::shared_ptr<RequestContext> ctx) {
if (FLAGS_enable_request_context) { if (FLAGS_enable_request_context) {
std::shared_ptr<RequestContext> old_ctx; std::shared_ptr<RequestContext> old_ctx;
if (getStaticContext().get()) { if (getStaticContext()) {
old_ctx = *getStaticContext().get(); old_ctx = getStaticContext();
}
if (ctx == nullptr) {
getStaticContext().reset(nullptr);
} else {
getStaticContext().reset(new std::shared_ptr<RequestContext>(ctx));
} }
getStaticContext() = ctx;
return old_ctx; return old_ctx;
} }
return std::shared_ptr<RequestContext>(); return nullptr;
} }
static std::shared_ptr<RequestContext> saveContext() { static std::shared_ptr<RequestContext> saveContext() {
if (!FLAGS_enable_request_context) { return getStaticContext();
return std::shared_ptr<RequestContext>();
}
if (getStaticContext().get() == nullptr) {
return std::shared_ptr<RequestContext>();
} else {
return *getStaticContext().get();
}
} }
// Used to solve static destruction ordering issue. Any static object // Used to solve static destruction ordering issue. Any static object
...@@ -168,10 +153,10 @@ class RequestContext { ...@@ -168,10 +153,10 @@ class RequestContext {
// See below link for more details. // See below link for more details.
// http://stackoverflow.com/questions/335369/ // http://stackoverflow.com/questions/335369/
// finding-c-static-initialization-order-problems#335746 // finding-c-static-initialization-order-problems#335746
static folly::ThreadLocalPtr<std::shared_ptr<RequestContext>>& static std::shared_ptr<RequestContext>&
getStaticContext() { getStaticContext() {
static folly::ThreadLocalPtr<std::shared_ptr<RequestContext> > context; static folly::ThreadLocal<std::shared_ptr<RequestContext> > context;
return context; return *context;
} }
private: private:
...@@ -179,24 +164,4 @@ class RequestContext { ...@@ -179,24 +164,4 @@ class RequestContext {
std::map<std::string, std::unique_ptr<RequestData>> data_; std::map<std::string, std::unique_ptr<RequestData>> data_;
}; };
/**
* Set the request context for a specific scope. For example,
* if you ran a part of a request in another thread you could
* use RequestContextGuard to copy apply the request context
* inside the other therad.
*/
class RequestContextGuard {
public:
explicit RequestContextGuard(std::shared_ptr<RequestContext> ctx) {
oldctx_ = RequestContext::setContext(std::move(ctx));
}
~RequestContextGuard() {
RequestContext::setContext(std::move(oldctx_));
}
private:
std::shared_ptr<RequestContext> oldctx_;
};
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment