/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <atomic> #include <memory> #include <string> #include <type_traits> #include <utility> #include <folly/SharedMutex.h> #include <folly/SingletonThreadLocal.h> #include <folly/Synchronized.h> #include <folly/concurrency/ProcessLocalUniqueId.h> #include <folly/container/F14Map.h> #include <folly/detail/Iterators.h> #include <folly/synchronization/Hazptr.h> namespace folly { /* * A token to be used to fetch data from RequestContext. * Generally you will want this to be a static, created only once using a * string, and then only copied. The string constructor is expensive. */ class RequestToken { … }; static_assert …; } // namespace folly namespace std { template <> struct hash<folly::RequestToken> { … }; } // namespace std namespace folly { // Some request context that follows an async request through a process // Everything in the context must be thread safe class RequestData { … }; /** * ImmutableRequestData is a folly::RequestData that holds an immutable value. * It is thread-safe (a requirement of RequestData) because it is immutable. */ template <typename T> class ImmutableRequestData : public folly::RequestData { … }; RequestDataItem; class RequestContext { … }; static_assert …; /** * RequestContextSaverScopeGuard allows to replace the current context * without switching back to original context, while ensuring that the original * context is restored on guard destruction. * * The constructor saves the current context but does not replace it; instead, * RequestContext::setContext() should be called directly. The original context * will be restored on guard destruction. This is different from * RequestContextScopeGuard which replaces the current context in construction. * * This enables taking advantage of the optimization in setContext() which skips * invoking the RequestData callbacks if the new context is the the same as the * current one. The use case is processing tasks in a loop which are likely to * share the same context. */ class RequestContextSaverScopeGuard { … }; /** * Note: you probably want to use ShallowCopyRequestContextScopeGuard * This resets all other RequestData for the duration of the scope! */ class RequestContextScopeGuard : private RequestContextSaverScopeGuard { … }; /** * This guard maintains all the RequestData pointers of the parent. * This allows to overwrite a specific RequestData pointer for the * scope's duration, without breaking others. * * Only modified pointers will have their set/onset methods called */ struct ShallowCopyRequestContextScopeGuard { … }; template <class Traits> /* static */ FOLLY_EXPORT RequestData* RequestContext::getThreadCachedContextData() { … } } // namespace folly