Commit 1c6da6e3 authored by Jon Maltiel Swenson's avatar Jon Maltiel Swenson Committed by Facebook Github Bot

Backed out changeset ea9041ce2280

Summary: Revert D5787837. Breaks `onSet()`/`onUnset()` behavior.

Reviewed By: palmtenor

Differential Revision: D5817063

fbshipit-source-id: c7dea636fa60eb616d4ebe0a9d418bc96b3018ae
parent d5005766
main v2022.02.14.00 v2022.02.07.00 v2022.01.31.00 v2022.01.24.00 v2022.01.17.00 v2022.01.10.00 v2022.01.03.00 v2021.12.27.00 v2021.12.20.00 v2021.12.13.00 v2021.12.06.00 v2021.11.29.00 v2021.11.15.00 v2021.11.08.00 v2021.11.01.00 v2021.10.25.00 v2021.10.18.00 v2021.10.11.00 v2021.10.04.00 v2021.09.27.00 v2021.09.20.00 v2021.09.13.00 v2021.09.06.00 v2021.08.30.00 v2021.08.23.00 v2021.08.02.00 v2021.07.22.00 v2021.07.20.01 v2021.07.20.00 v2021.06.28.00 v2021.06.14.00 v2021.06.07.00 v2021.05.31.00 v2021.05.24.00 v2021.05.17.00 v2021.05.10.00 v2021.05.03.00 v2021.04.26.00 v2021.04.19.00 v2021.04.12.00 v2021.04.05.00 v2021.03.29.00 v2021.03.22.00 v2021.03.15.00 v2021.03.08.00 v2021.03.01.00 v2021.02.22.00 v2021.02.15.00 v2021.02.08.00 v2021.02.01.00 v2021.01.25.00 v2021.01.18.01 v2021.01.18.00 v2021.01.11.00 v2021.01.04.00 v2020.12.28.00 v2020.12.21.00 v2020.12.14.00 v2020.12.07.00 v2020.11.30.00 v2020.11.23.00 v2020.11.16.00 v2020.11.09.00 v2020.11.02.00 v2020.10.26.00 v2020.10.19.00 v2020.10.12.00 v2020.10.05.00 v2020.09.28.00 v2020.09.21.00 v2020.09.14.00 v2020.09.07.00 v2020.08.31.00 v2020.08.24.00 v2020.08.17.00 v2020.08.10.00 v2020.08.03.00 v2020.07.27.00 v2020.07.20.00 v2020.07.13.00 v2020.07.06.00 v2020.06.29.00 v2020.06.15.00 v2020.06.08.00 v2020.06.01.00 v2020.05.25.00 v2020.05.18.00 v2020.05.11.00 v2020.05.04.00 v2020.04.27.00 v2020.04.20.00 v2020.04.13.00 v2020.04.06.00 v2020.03.30.00 v2020.03.23.00 v2020.03.16.00 v2020.03.09.00 v2020.03.02.00 v2020.02.24.00 v2020.02.17.00 v2020.02.10.00 v2020.02.03.00 v2020.01.27.00 v2020.01.20.00 v2020.01.13.00 v2020.01.06.00 v2019.12.30.00 v2019.12.23.00 v2019.12.16.00 v2019.12.09.00 v2019.12.06.00 v2019.12.02.00 v2019.11.11.00 v2019.11.04.00 v2019.10.28.00 v2019.10.21.00 v2019.10.14.00 v2019.10.07.00 v2019.09.30.00 v2019.09.23.00 v2019.09.16.00 v2019.09.09.00 v2019.09.02.00 v2019.08.26.00 v2019.08.19.00 v2019.08.12.00 v2019.08.05.00 v2019.07.29.00 v2019.07.22.00 v2019.06.17.00 v2019.06.10.00 v2019.06.03.00 v2019.05.27.00 v2019.05.20.00 v2019.05.13.00 v2019.05.06.00 v2019.04.29.00 v2019.04.22.00 v2019.04.15.00 v2019.04.08.00 v2019.04.01.00 v2019.03.25.00 v2019.03.18.00 v2019.03.04.00 v2019.02.25.00 v2019.02.18.00 v2019.02.11.00 v2019.02.04.00 v2019.01.28.00 v2019.01.21.00 v2019.01.14.00 v2019.01.07.00 v2018.12.31.00 v2018.12.24.00 v2018.12.17.00 v2018.12.10.00 v2018.12.03.00 v2018.11.26.00 v2018.11.19.00 v2018.11.12.00 v2018.11.05.00 v2018.10.29.00 v2018.10.22.00 v2018.10.15.00 v2018.10.08.00 v2018.10.01.00 v2018.09.24.00 v2018.09.17.00 v2018.09.10.01 v2018.09.10.00 v2018.09.03.01 v2018.09.03.00 v2018.08.27.00 v2018.08.20.00 v2018.08.13.00 v2018.08.09.00 v2018.08.06.00 v2018.07.30.00 v2018.07.23.00 v2018.07.16.00 v2018.07.09.00 v2018.07.02.00 v2018.06.25.00 v2018.06.18.00 v2018.06.11.00 v2018.06.04.00 v2018.05.28.00 v2018.05.21.00 v2018.05.14.00 v2018.05.07.00 v2018.04.30.00 v2018.04.23.00 v2018.04.16.00 v2018.04.09.00 v2018.04.02.00 v2018.03.26.00 v2018.03.19.00 v2018.03.12.00 v2018.03.05.00 v2018.02.26.00 v2018.02.19.00 v2018.02.12.00 v2018.02.05.00 v2018.01.29.00 v2018.01.22.00 v2018.01.15.00 v2018.01.08.00 v2018.01.01.00 v2017.12.25.00 v2017.12.18.00 v2017.12.11.00 v2017.12.04.00 v2017.11.27.00 v2017.11.20.00 v2017.11.13.00 v2017.11.06.00 v2017.10.30.00 v2017.10.23.00 v2017.10.16.00 v2017.10.09.00 v2017.10.02.00 v2017.09.25.00 v2017.09.18.00
No related merge requests found
...@@ -113,6 +113,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -113,6 +113,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
fiber->state_ == Fiber::NOT_STARTED || fiber->state_ == Fiber::NOT_STARTED ||
fiber->state_ == Fiber::READY_TO_RUN); fiber->state_ == Fiber::READY_TO_RUN);
currentFiber_ = fiber; currentFiber_ = fiber;
fiber->rcontext_ = RequestContext::setContext(std::move(fiber->rcontext_));
if (observer_) { if (observer_) {
observer_->starting(reinterpret_cast<uintptr_t>(fiber)); observer_->starting(reinterpret_cast<uintptr_t>(fiber));
} }
...@@ -138,6 +139,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -138,6 +139,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
observer_->stopped(reinterpret_cast<uintptr_t>(fiber)); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
fiber->rcontext_ = RequestContext::setContext(std::move(fiber->rcontext_));
} else if (fiber->state_ == Fiber::INVALID) { } else if (fiber->state_ == Fiber::INVALID) {
assert(fibersActive_ > 0); assert(fibersActive_ > 0);
--fibersActive_; --fibersActive_;
...@@ -159,6 +161,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -159,6 +161,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
observer_->stopped(reinterpret_cast<uintptr_t>(fiber)); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
fiber->rcontext_ = RequestContext::setContext(std::move(fiber->rcontext_));
fiber->localData_.reset(); fiber->localData_.reset();
fiber->rcontext_.reset(); fiber->rcontext_.reset();
...@@ -176,6 +179,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -176,6 +179,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
observer_->stopped(reinterpret_cast<uintptr_t>(fiber)); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
fiber->rcontext_ = RequestContext::setContext(std::move(fiber->rcontext_));
fiber->state_ = Fiber::READY_TO_RUN; fiber->state_ = Fiber::READY_TO_RUN;
yieldedFibers_.push_back(*fiber); yieldedFibers_.push_back(*fiber);
} }
...@@ -196,20 +200,8 @@ inline void FiberManager::loopUntilNoReadyImpl() { ...@@ -196,20 +200,8 @@ inline void FiberManager::loopUntilNoReadyImpl() {
auto originalFiberManager = this; auto originalFiberManager = this;
std::swap(currentFiberManager_, originalFiberManager); std::swap(currentFiberManager_, originalFiberManager);
RequestContext::Provider oldRequestContextProvider;
auto newRequestContextProvider =
[this, &oldRequestContextProvider]() -> std::shared_ptr<RequestContext>& {
return currentFiber_ ? currentFiber_->rcontext_
: oldRequestContextProvider();
};
oldRequestContextProvider = RequestContext::setRequestContextProvider(
std::ref(newRequestContextProvider));
SCOPE_EXIT { SCOPE_EXIT {
isLoopScheduled_ = false; isLoopScheduled_ = false;
// Restore RequestContext provider before call to ensureLoopScheduled()
RequestContext::setRequestContextProvider(
std::move(oldRequestContextProvider));
if (!readyFibers_.empty()) { if (!readyFibers_.empty()) {
ensureLoopScheduled(); ensureLoopScheduled();
} }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <folly/fibers/SimpleLoopController.h> #include <folly/fibers/SimpleLoopController.h>
#include <folly/fibers/TimedMutex.h> #include <folly/fibers/TimedMutex.h>
#include <folly/fibers/WhenN.h> #include <folly/fibers/WhenN.h>
#include <folly/io/async/Request.h>
#include <folly/io/async/ScopedEventBaseThread.h> #include <folly/io/async/ScopedEventBaseThread.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
...@@ -1237,107 +1236,6 @@ TEST(FiberManager, fiberLocalDestructor) { ...@@ -1237,107 +1236,6 @@ TEST(FiberManager, fiberLocalDestructor) {
EXPECT_FALSE(fm.hasTasks()); EXPECT_FALSE(fm.hasTasks());
} }
TEST(FiberManager, fiberRequestContext) {
folly::EventBase evb;
FiberManager fm(std::make_unique<EventBaseLoopController>());
dynamic_cast<EventBaseLoopController&>(fm.loopController())
.attachEventBase(evb);
struct TestContext : public folly::RequestData {
explicit TestContext(std::string s) : data(std::move(s)) {}
std::string data;
};
class AfterFibersCallback : public folly::EventBase::LoopCallback {
public:
AfterFibersCallback(
folly::EventBase& evb,
const bool& fibersDone,
folly::Function<void()> afterFibersFunc)
: evb_(evb),
fibersDone_(fibersDone),
afterFibersFunc_(std::move(afterFibersFunc)) {}
void runLoopCallback() noexcept override {
if (fibersDone_) {
afterFibersFunc_();
delete this;
} else {
evb_.runInLoop(this);
}
}
private:
folly::EventBase& evb_;
const bool& fibersDone_;
folly::Function<void()> afterFibersFunc_;
};
bool fibersDone = false;
size_t tasksRun = 0;
evb.runInEventBaseThread([&evb, &fm, &tasksRun, &fibersDone]() {
++tasksRun;
auto* const evbCtx = folly::RequestContext::get();
EXPECT_NE(nullptr, evbCtx);
EXPECT_EQ(nullptr, evbCtx->getContextData("key"));
evbCtx->setContextData("key", std::make_unique<TestContext>("evb_value"));
// This callback allows us to check that FiberManager has restored the
// RequestContext provider as expected after a fiber loop.
auto* afterFibersCallback =
new AfterFibersCallback(evb, fibersDone, [&tasksRun, evbCtx]() {
++tasksRun;
EXPECT_EQ(evbCtx, folly::RequestContext::get());
EXPECT_EQ(
"evb_value",
dynamic_cast<TestContext*>(evbCtx->getContextData("key"))->data);
});
evb.runInLoop(afterFibersCallback);
// Launching a fiber allows us to hit FiberManager RequestContext
// setup/teardown logic.
fm.addTask([&evb, &tasksRun, &fibersDone, evbCtx]() {
++tasksRun;
// Initially, fiber starts with same RequestContext as its parent task.
EXPECT_EQ(evbCtx, folly::RequestContext::get());
EXPECT_NE(nullptr, evbCtx->getContextData("key"));
EXPECT_EQ(
"evb_value",
dynamic_cast<TestContext*>(evbCtx->getContextData("key"))->data);
// Create a new RequestContext for this fiber so we can distinguish from
// RequestContext first EventBase callback started with.
folly::RequestContext::create();
auto* const fiberCtx = folly::RequestContext::get();
EXPECT_NE(nullptr, fiberCtx);
EXPECT_EQ(nullptr, fiberCtx->getContextData("key"));
fiberCtx->setContextData(
"key", std::make_unique<TestContext>("fiber_value"));
// Task launched from within fiber should share current fiber's
// RequestContext
evb.runInEventBaseThread([&tasksRun, fiberCtx]() {
++tasksRun;
auto* const evbCtx2 = folly::RequestContext::get();
EXPECT_EQ(fiberCtx, evbCtx2);
EXPECT_NE(nullptr, evbCtx2->getContextData("key"));
EXPECT_EQ(
"fiber_value",
dynamic_cast<TestContext*>(evbCtx2->getContextData("key"))->data);
});
fibersDone = true;
});
});
evb.loop();
EXPECT_EQ(4, tasksRun);
EXPECT_TRUE(fibersDone);
EXPECT_FALSE(fm.hasTasks());
}
TEST(FiberManager, yieldTest) { TEST(FiberManager, yieldTest) {
FiberManager manager(std::make_unique<SimpleLoopController>()); FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController = auto& loopController =
......
...@@ -13,17 +13,14 @@ ...@@ -13,17 +13,14 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <folly/io/async/Request.h>
#include <algorithm> #include <folly/io/async/Request.h>
#include <stdexcept> #include <folly/tracing/StaticTracepoint.h>
#include <utility>
#include <glog/logging.h> #include <glog/logging.h>
#include <folly/MapUtil.h> #include <folly/MapUtil.h>
#include <folly/SingletonThreadLocal.h> #include <folly/SingletonThreadLocal.h>
#include <folly/tracing/StaticTracepoint.h>
namespace folly { namespace folly {
...@@ -118,50 +115,19 @@ std::shared_ptr<RequestContext> RequestContext::setContext( ...@@ -118,50 +115,19 @@ std::shared_ptr<RequestContext> RequestContext::setContext(
return ctx; return ctx;
} }
RequestContext::Provider& RequestContext::requestContextProvider() {
class DefaultProvider {
public:
constexpr DefaultProvider() = default;
DefaultProvider(const DefaultProvider&) = delete;
DefaultProvider& operator=(const DefaultProvider&) = delete;
DefaultProvider(DefaultProvider&&) = default;
DefaultProvider& operator=(DefaultProvider&&) = default;
std::shared_ptr<RequestContext>& operator()() {
return context;
}
private:
std::shared_ptr<RequestContext> context;
};
static SingletonThreadLocal<Provider> providerSingleton(
[]() { return new Provider(DefaultProvider()); });
return providerSingleton.get();
}
std::shared_ptr<RequestContext>& RequestContext::getStaticContext() { std::shared_ptr<RequestContext>& RequestContext::getStaticContext() {
auto& provider = requestContextProvider(); using SingletonT = SingletonThreadLocal<std::shared_ptr<RequestContext>>;
return provider(); static SingletonT singleton;
return singleton.get();
} }
RequestContext* RequestContext::get() { RequestContext* RequestContext::get() {
auto& context = getStaticContext(); auto context = getStaticContext();
if (!context) { if (!context) {
static RequestContext defaultContext; static RequestContext defaultContext;
return std::addressof(defaultContext); return std::addressof(defaultContext);
} }
return context.get(); return context.get();
} }
RequestContext::Provider RequestContext::setRequestContextProvider(
RequestContext::Provider newProvider) {
if (!newProvider) {
throw std::runtime_error("RequestContext provider must be non-empty");
}
auto& provider = requestContextProvider();
std::swap(provider, newProvider);
return newProvider;
}
} }
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <folly/Function.h>
#include <folly/SharedMutex.h> #include <folly/SharedMutex.h>
#include <folly/Synchronized.h> #include <folly/Synchronized.h>
...@@ -46,8 +45,6 @@ class RequestContext; ...@@ -46,8 +45,6 @@ class RequestContext;
// copied between threads. // copied between threads.
class RequestContext { class RequestContext {
public: public:
using Provider = folly::Function<std::shared_ptr<RequestContext>&()>;
// Create a unique request context for this request. // Create a unique request 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.
...@@ -98,22 +95,8 @@ class RequestContext { ...@@ -98,22 +95,8 @@ class RequestContext {
return getStaticContext(); return getStaticContext();
} }
// This API allows one to override the default behavior of getStaticContext()
// by providing a custom RequestContext provider. The old provider is
// returned, and the user must restore the old provider via a subsequent call
// to setRequestContextProvider() once the new provider is no longer needed.
//
// Using custom RequestContext providers can be more efficient than having to
// setContext() whenever context must be switched. This is especially true in
// applications that do not actually use RequestContext, but where library
// code must still support RequestContext for other use cases. See
// FiberManager for an example of how a custom RequestContext provider can
// reduce calls to setContext().
static Provider setRequestContextProvider(Provider f);
private: private:
static std::shared_ptr<RequestContext>& getStaticContext(); static std::shared_ptr<RequestContext>& getStaticContext();
static Provider& requestContextProvider();
using Data = std::map<std::string, std::unique_ptr<RequestData>>; using Data = std::map<std::string, std::unique_ptr<RequestData>>;
folly::Synchronized<Data, folly::SharedMutex> data_; folly::Synchronized<Data, folly::SharedMutex> data_;
......
...@@ -77,49 +77,6 @@ TEST(RequestContext, SimpleTest) { ...@@ -77,49 +77,6 @@ TEST(RequestContext, SimpleTest) {
EXPECT_TRUE(nullptr != RequestContext::get()); EXPECT_TRUE(nullptr != RequestContext::get());
} }
TEST(RequestContext, nonDefaultContextsAreThreadLocal) {
RequestContext* ctx1 = nullptr;
RequestContext* ctx2 = nullptr;
std::vector<std::thread> ts;
for (size_t i = 0; i < 2; ++i) {
auto*& ctx = (i == 0 ? ctx1 : ctx2);
ts.emplace_back([&ctx]() {
RequestContext::create();
ctx = RequestContext::get();
});
}
for (auto& t : ts) {
t.join();
}
EXPECT_NE(nullptr, ctx1);
EXPECT_NE(nullptr, ctx2);
EXPECT_NE(ctx1, ctx2);
}
TEST(RequestContext, customRequestContextProvider) {
auto customContext = std::make_shared<RequestContext>();
auto customProvider = [&customContext]() -> std::shared_ptr<RequestContext>& {
return customContext;
};
auto* const originalContext = RequestContext::get();
EXPECT_NE(nullptr, originalContext);
// Install new RequestContext provider
auto originalProvider =
RequestContext::setRequestContextProvider(std::move(customProvider));
auto* const newContext = RequestContext::get();
EXPECT_EQ(customContext.get(), newContext);
EXPECT_NE(originalContext, newContext);
// Restore original RequestContext provider
RequestContext::setRequestContextProvider(std::move(originalProvider));
EXPECT_EQ(originalContext, RequestContext::get());
}
TEST(RequestContext, setIfAbsentTest) { TEST(RequestContext, setIfAbsentTest) {
EXPECT_TRUE(RequestContext::get() != nullptr); EXPECT_TRUE(RequestContext::get() != nullptr);
......
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