cleaning up RequestContext
[folly.git] / folly / io / async / Request.h
index 9d1ff119581a452ea1321c4685298c86a596ee2a..490c69b08a26c566a87f43175c7ccf8e0a84f9f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
  *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
 #include <folly/ThreadLocal.h>
 #include <folly/RWSpinLock.h>
 
-/**
- * In many cases this header is included as a
- * dependency to libraries which do not need
- * command line flags. GFLAGS is a large binary
- * and thus we do this so that a library which
- * is size sensitive doesn't have to pull in
- * GFLAGS if it doesn't want to.
- */
-#ifndef NO_LIB_GFLAGS
-  #include <gflags/gflags.h>
-  DECLARE_bool(enable_request_context);
-#endif
-
 namespace folly {
 
-#ifdef NO_LIB_GFLAGS
-  extern bool FLAGS_enable_request_context;
-#endif
-
 // Some request context that follows an async request through a process
 // Everything in the context must be thread safe
 
@@ -58,33 +41,23 @@ class RequestContext;
 // If you do not call create() to create a unique request context,
 // this default request context will always be returned, and is never
 // copied between threads.
-extern RequestContext* defaultContext;
-
 class RequestContext {
  public:
   // Create a unique requext context for this request.
   // It will be passed between queues / threads (where implemented),
   // so it should be valid for the lifetime of the request.
-  static bool create() {
-    if(!FLAGS_enable_request_context) {
-      return false;
-    }
-    bool prev = getStaticContext().get() != nullptr;
-    getStaticContext().reset(new std::shared_ptr<RequestContext>(
-                     std::make_shared<RequestContext>()));
-    return prev;
+  static void create() {
+    getStaticContext() = std::make_shared<RequestContext>();
   }
 
   // Get the current context.
   static RequestContext* get() {
-    if (!FLAGS_enable_request_context ||
-        getStaticContext().get() == nullptr) {
-      if (defaultContext == nullptr) {
-        defaultContext = new RequestContext;
-      }
-      return defaultContext;
+    auto context = getStaticContext();
+    if (!context) {
+      static RequestContext defaultContext;
+      return std::addressof(defaultContext);
     }
-    return getStaticContext().get()->get();
+    return context.get();
   }
 
   // The following API may be used to set per-request data in a thread-safe way.
@@ -92,10 +65,6 @@ class RequestContext {
   // profiling any use of these functions.
   void setContextData(
     const std::string& val, std::unique_ptr<RequestData> data) {
-    if (!FLAGS_enable_request_context) {
-      return;
-    }
-
     folly::RWSpinLock::WriteHolder guard(lock);
     if (data_.find(val) != data_.end()) {
       LOG_FIRST_N(WARNING, 1) <<
@@ -136,67 +105,29 @@ class RequestContext {
 
   static std::shared_ptr<RequestContext>
   setContext(std::shared_ptr<RequestContext> ctx) {
-    if (FLAGS_enable_request_context) {
-      std::shared_ptr<RequestContext> old_ctx;
-      if (getStaticContext().get()) {
-        old_ctx = *getStaticContext().get();
-      }
-      if (ctx == nullptr) {
-        getStaticContext().reset(nullptr);
-      } else {
-        getStaticContext().reset(new std::shared_ptr<RequestContext>(ctx));
-      }
-      return old_ctx;
-    }
-    return std::shared_ptr<RequestContext>();
+    using std::swap;
+    swap(ctx, getStaticContext());
+    return ctx;
   }
 
   static std::shared_ptr<RequestContext> saveContext() {
-    if (!FLAGS_enable_request_context) {
-      return std::shared_ptr<RequestContext>();
-    }
-    if (getStaticContext().get() == nullptr) {
-      return std::shared_ptr<RequestContext>();
-    } else {
-      return *getStaticContext().get();
-    }
+    return getStaticContext();
   }
 
+ private:
   // Used to solve static destruction ordering issue.  Any static object
   // that uses RequestContext must call this function in its constructor.
   //
   // See below link for more details.
   // http://stackoverflow.com/questions/335369/
   // finding-c-static-initialization-order-problems#335746
-  static folly::ThreadLocalPtr<std::shared_ptr<RequestContext>>&
-  getStaticContext() {
-    static folly::ThreadLocalPtr<std::shared_ptr<RequestContext> > context;
-    return context;
+  static std::shared_ptr<RequestContext> &getStaticContext() {
+    static folly::ThreadLocal<std::shared_ptr<RequestContext> > context;
+    return *context;
   }
 
- private:
   folly::RWSpinLock lock;
   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_;
-};
-
 }