react-native-windows 0.83.0 → 0.83.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/unicode.cpp +36 -0
- package/Common/unicode.h +8 -0
- package/Directory.Build.props +2 -17
- package/Folly/ThreadNameStub.cpp +4 -6
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +17 -4
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +6 -4
- package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +8 -4
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +4 -9
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -3
- package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +3 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +33 -25
- package/Microsoft.ReactNative/Utils/LocalBundleReader.h +5 -3
- package/Microsoft.ReactNative/Utils/UwpScriptStore.cpp +2 -2
- package/Microsoft.ReactNative/Utils/UwpScriptStore.h +3 -2
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +16 -0
- package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +3 -3
- package/Microsoft.ReactNative.Managed.CodeGen/Microsoft.ReactNative.Managed.CodeGen.csproj +10 -10
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml +1 -1
- package/PropertySheets/CIBuildOptimizations.props +2 -2
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/NuGet.LockFile.props +9 -1
- package/PropertySheets/React.Cpp.props +7 -6
- package/PropertySheets/WinUI.props +4 -3
- package/ReactCommon/ReactCommon.vcxproj +0 -5
- package/Scripts/ConfigureYarnPackageAgeGate.ps1 +25 -0
- package/Scripts/EnableInternalWinAppSDKFeed.ps1 +12 -5
- package/Scripts/JustMyXaml.ps1 +8 -8
- package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +103 -6
- package/Scripts/RunRnwInitWindows.js +37 -0
- package/Scripts/Tfs/Layout-Desktop-Headers.ps1 +4 -37
- package/Scripts/UnitTest.ps1 +3 -1
- package/Scripts/UpdateNightlyDependencies.ps1 +47 -0
- package/Scripts/creaternwapp.cmd +35 -12
- package/Scripts/creaternwlib.cmd +41 -18
- package/Scripts/rnw-dependencies.ps1 +15 -16
- package/Shared/DevSupportManager.cpp +55 -48
- package/Shared/DevSupportManager.h +0 -1
- package/Shared/Modules/IWebSocketModuleContentHandler.h +15 -0
- package/Shared/Modules/WebSocketModule.cpp +8 -3
- package/Shared/Networking/DefaultBlobResource.cpp +37 -0
- package/Shared/Networking/DefaultBlobResource.h +12 -0
- package/Shared/Networking/WinRTWebSocketResource.h +5 -1
- package/Shared/Shared.vcxitems +2 -0
- package/{Folly → external}/.clang-format +0 -1
- package/external/External.vcxitems +10 -0
- package/external/fast-float/.syncignore +10 -0
- package/external/fast-float/LICENSE-APACHE +190 -0
- package/external/fast-float/LICENSE-BOOST +23 -0
- package/external/fast-float/LICENSE-MIT +27 -0
- package/external/fast-float/README.md +545 -0
- package/external/fast-float/cgmanifest.json +15 -0
- package/external/fast-float/fast-float.vcxitems +14 -0
- package/external/fast-float/include/fast_float/ascii_number.h +588 -0
- package/external/fast-float/include/fast_float/bigint.h +638 -0
- package/external/fast-float/include/fast_float/constexpr_feature_detect.h +46 -0
- package/external/fast-float/include/fast_float/decimal_to_binary.h +212 -0
- package/external/fast-float/include/fast_float/digit_comparison.h +457 -0
- package/external/fast-float/include/fast_float/fast_float.h +59 -0
- package/external/fast-float/include/fast_float/fast_table.h +708 -0
- package/external/fast-float/include/fast_float/float_common.h +1240 -0
- package/external/fast-float/include/fast_float/parse_number.h +399 -0
- package/external/fast-float/sync-config.json +8 -0
- package/external/fmt/.syncignore +10 -0
- package/external/fmt/CONTRIBUTING.md +20 -0
- package/external/fmt/LICENSE +27 -0
- package/external/fmt/README.md +484 -0
- package/external/fmt/doc/ChangeLog-old.md +3290 -0
- package/external/fmt/doc/api.md +650 -0
- package/external/fmt/doc/fmt.css +61 -0
- package/external/fmt/doc/fmt.js +4 -0
- package/external/fmt/doc/get-started.md +222 -0
- package/external/fmt/doc/index.md +151 -0
- package/external/fmt/doc/perf.svg +1 -0
- package/external/fmt/doc/python-license.txt +290 -0
- package/external/fmt/doc/syntax.md +887 -0
- package/external/fmt/fmt.vcxitems +28 -0
- package/external/fmt/include/fmt/args.h +228 -0
- package/external/fmt/include/fmt/base.h +3077 -0
- package/external/fmt/include/fmt/chrono.h +2432 -0
- package/external/fmt/include/fmt/color.h +612 -0
- package/external/fmt/include/fmt/compile.h +529 -0
- package/external/fmt/include/fmt/core.h +5 -0
- package/external/fmt/include/fmt/format-inl.h +1928 -0
- package/external/fmt/include/fmt/format.h +4427 -0
- package/external/fmt/include/fmt/os.h +439 -0
- package/external/fmt/include/fmt/ostream.h +211 -0
- package/external/fmt/include/fmt/printf.h +656 -0
- package/external/fmt/include/fmt/ranges.h +882 -0
- package/external/fmt/include/fmt/std.h +699 -0
- package/external/fmt/include/fmt/xchar.h +322 -0
- package/external/fmt/src/fmt.cc +135 -0
- package/external/fmt/src/format.cc +43 -0
- package/external/fmt/src/os.cc +403 -0
- package/external/fmt/sync-config.json +8 -0
- package/external/folly/.syncignore +60 -0
- package/external/folly/LICENSE +200 -0
- package/external/folly/README.md +263 -0
- package/{fmt → external/folly/folly}/.clang-format +0 -1
- package/external/folly/folly/AtomicHashArray-inl.h +546 -0
- package/external/folly/folly/AtomicHashArray.h +431 -0
- package/external/folly/folly/AtomicHashMap-inl.h +653 -0
- package/external/folly/folly/AtomicHashMap.h +484 -0
- package/external/folly/folly/AtomicIntrusiveLinkedList.h +206 -0
- package/external/folly/folly/AtomicLinkedList.h +110 -0
- package/external/folly/folly/AtomicUnorderedMap.h +522 -0
- package/external/folly/folly/BUCK +1631 -0
- package/external/folly/folly/BUILD_MODE.bzl +72 -0
- package/external/folly/folly/Benchmark.cpp +986 -0
- package/external/folly/folly/Benchmark.h +680 -0
- package/external/folly/folly/BenchmarkUtil.h +47 -0
- package/external/folly/folly/Bits.h +17 -0
- package/external/folly/folly/CMakeLists.txt +110 -0
- package/external/folly/folly/CPortability.h +338 -0
- package/external/folly/folly/CancellationToken-inl.h +449 -0
- package/external/folly/folly/CancellationToken.cpp +250 -0
- package/external/folly/folly/CancellationToken.h +365 -0
- package/external/folly/folly/Chrono.h +132 -0
- package/external/folly/folly/ClockGettimeWrappers.cpp +93 -0
- package/external/folly/folly/ClockGettimeWrappers.h +29 -0
- package/external/folly/folly/ConcurrentBitSet.h +157 -0
- package/external/folly/folly/ConcurrentLazy.h +74 -0
- package/external/folly/folly/ConcurrentSkipList-inl.h +341 -0
- package/external/folly/folly/ConcurrentSkipList.h +824 -0
- package/external/folly/folly/ConstructorCallbackList.h +158 -0
- package/external/folly/folly/Conv.h +2026 -0
- package/external/folly/folly/CppAttributes.h +170 -0
- package/external/folly/folly/CpuId.h +297 -0
- package/external/folly/folly/DefaultKeepAliveExecutor.h +172 -0
- package/external/folly/folly/Demangle.cpp +255 -0
- package/external/folly/folly/Demangle.h +73 -0
- package/external/folly/folly/DiscriminatedPtr.h +236 -0
- package/external/folly/folly/DynamicConverter.h +17 -0
- package/external/folly/folly/Exception.h +150 -0
- package/external/folly/folly/ExceptionString.cpp +51 -0
- package/external/folly/folly/ExceptionString.h +33 -0
- package/external/folly/folly/ExceptionWrapper-inl.h +264 -0
- package/external/folly/folly/ExceptionWrapper.cpp +37 -0
- package/external/folly/folly/ExceptionWrapper.h +377 -0
- package/external/folly/folly/Executor.cpp +111 -0
- package/external/folly/folly/Executor.h +351 -0
- package/external/folly/folly/Expected.h +1725 -0
- package/external/folly/folly/FBString.h +2888 -0
- package/external/folly/folly/FBVector.h +17 -0
- package/external/folly/folly/File.cpp +180 -0
- package/external/folly/folly/File.h +177 -0
- package/external/folly/folly/FileUtil.cpp +378 -0
- package/external/folly/folly/FileUtil.h +332 -0
- package/external/folly/folly/Fingerprint.cpp +135 -0
- package/external/folly/folly/Fingerprint.h +289 -0
- package/external/folly/folly/FixedString.h +2965 -0
- package/external/folly/folly/FollyMemcpy.cpp +30 -0
- package/external/folly/folly/FollyMemcpy.h +23 -0
- package/external/folly/folly/FollyMemset.cpp +29 -0
- package/external/folly/folly/FollyMemset.h +25 -0
- package/external/folly/folly/Format-inl.h +1152 -0
- package/external/folly/folly/Format.cpp +429 -0
- package/external/folly/folly/Format.h +463 -0
- package/external/folly/folly/FormatArg.h +285 -0
- package/external/folly/folly/FormatTraits.h +65 -0
- package/external/folly/folly/Function.h +1159 -0
- package/external/folly/folly/GLog.h +85 -0
- package/external/folly/folly/GroupVarint.cpp +153 -0
- package/external/folly/folly/GroupVarint.h +630 -0
- package/external/folly/folly/Hash.h +20 -0
- package/external/folly/folly/IPAddress.cpp +490 -0
- package/external/folly/folly/IPAddress.h +667 -0
- package/external/folly/folly/IPAddressException.h +82 -0
- package/external/folly/folly/IPAddressV4.cpp +305 -0
- package/external/folly/folly/IPAddressV4.h +495 -0
- package/external/folly/folly/IPAddressV6.cpp +541 -0
- package/external/folly/folly/IPAddressV6.h +627 -0
- package/external/folly/folly/Indestructible.h +164 -0
- package/external/folly/folly/IndexedMemPool.h +550 -0
- package/external/folly/folly/IntrusiveList.h +17 -0
- package/external/folly/folly/Lazy.h +142 -0
- package/external/folly/folly/Likely.h +76 -0
- package/external/folly/folly/MPMCPipeline.h +280 -0
- package/external/folly/folly/MPMCQueue.h +1556 -0
- package/external/folly/folly/MacAddress.cpp +188 -0
- package/external/folly/folly/MacAddress.h +260 -0
- package/external/folly/folly/MapUtil.h +17 -0
- package/external/folly/folly/Math.h +258 -0
- package/external/folly/folly/MaybeManagedPtr.h +120 -0
- package/external/folly/folly/Memory.h +900 -0
- package/external/folly/folly/MicroLock.cpp +76 -0
- package/external/folly/folly/MicroLock.h +354 -0
- package/external/folly/folly/MicroSpinLock.h +17 -0
- package/external/folly/folly/MoveWrapper.h +76 -0
- package/external/folly/folly/ObserverContainer.h +1026 -0
- package/external/folly/folly/Optional.h +743 -0
- package/external/folly/folly/Overload.h +325 -0
- package/external/folly/folly/PackedSyncPtr.h +147 -0
- package/external/folly/folly/Padded.h +464 -0
- package/external/folly/folly/Poly-inl.h +230 -0
- package/external/folly/folly/Poly.h +1095 -0
- package/external/folly/folly/PolyException.h +43 -0
- package/external/folly/folly/Portability.h +644 -0
- package/external/folly/folly/Preprocessor.h +236 -0
- package/external/folly/folly/ProducerConsumerQueue.h +182 -0
- package/external/folly/folly/RWSpinLock.h +17 -0
- package/external/folly/folly/Random-inl.h +86 -0
- package/external/folly/folly/Random.cpp +184 -0
- package/external/folly/folly/Random.h +434 -0
- package/external/folly/folly/Range.h +1772 -0
- package/external/folly/folly/Replaceable.h +636 -0
- package/external/folly/folly/ScopeGuard.cpp +29 -0
- package/external/folly/folly/ScopeGuard.h +420 -0
- package/external/folly/folly/SharedMutex.cpp +81 -0
- package/external/folly/folly/SharedMutex.h +1751 -0
- package/external/folly/folly/Singleton-inl.h +332 -0
- package/external/folly/folly/Singleton.cpp +512 -0
- package/external/folly/folly/Singleton.h +891 -0
- package/external/folly/folly/SingletonThreadLocal.cpp +53 -0
- package/external/folly/folly/SingletonThreadLocal.h +263 -0
- package/external/folly/folly/SocketAddress.cpp +786 -0
- package/external/folly/folly/SocketAddress.h +768 -0
- package/external/folly/folly/SpinLock.h +55 -0
- package/external/folly/folly/String-inl.h +668 -0
- package/external/folly/folly/String.cpp +777 -0
- package/external/folly/folly/String.h +767 -0
- package/external/folly/folly/Subprocess.cpp +1142 -0
- package/external/folly/folly/Subprocess.h +1055 -0
- package/external/folly/folly/Synchronized.h +1833 -0
- package/external/folly/folly/SynchronizedPtr.h +106 -0
- package/external/folly/folly/ThreadCachedInt.h +175 -0
- package/external/folly/folly/ThreadLocal.h +478 -0
- package/external/folly/folly/TimeoutQueue.cpp +78 -0
- package/external/folly/folly/TimeoutQueue.h +123 -0
- package/external/folly/folly/TokenBucket.h +673 -0
- package/external/folly/folly/Traits.h +1442 -0
- package/external/folly/folly/Try-inl.h +372 -0
- package/external/folly/folly/Try.cpp +23 -0
- package/external/folly/folly/Try.h +728 -0
- package/external/folly/folly/UTF8String.h +56 -0
- package/external/folly/folly/Unicode.cpp +201 -0
- package/external/folly/folly/Unicode.h +94 -0
- package/external/folly/folly/Unit.h +65 -0
- package/external/folly/folly/Uri-inl.h +101 -0
- package/external/folly/folly/Uri.cpp +190 -0
- package/external/folly/folly/Uri.h +142 -0
- package/external/folly/folly/Utility.h +932 -0
- package/external/folly/folly/VERSION +1 -0
- package/external/folly/folly/Varint.h +230 -0
- package/external/folly/folly/VirtualExecutor.h +17 -0
- package/external/folly/folly/algorithm/simd/BUCK +47 -0
- package/external/folly/folly/algorithm/simd/Contains.cpp +42 -0
- package/external/folly/folly/algorithm/simd/Contains.h +116 -0
- package/external/folly/folly/algorithm/simd/FindFixed.h +301 -0
- package/external/folly/folly/algorithm/simd/Ignore.h +52 -0
- package/external/folly/folly/algorithm/simd/Movemask.h +207 -0
- package/external/folly/folly/algorithm/simd/detail/BUCK +70 -0
- package/external/folly/folly/algorithm/simd/detail/ContainsImpl.h +91 -0
- package/external/folly/folly/algorithm/simd/detail/SimdAnyOf.h +83 -0
- package/external/folly/folly/algorithm/simd/detail/SimdForEach.h +209 -0
- package/external/folly/folly/algorithm/simd/detail/SimdPlatform.h +445 -0
- package/external/folly/folly/algorithm/simd/detail/Traits.h +125 -0
- package/external/folly/folly/algorithm/simd/detail/UnrollUtils.h +126 -0
- package/external/folly/folly/base64.h +264 -0
- package/external/folly/folly/chrono/BUCK +29 -0
- package/external/folly/folly/chrono/Clock.h +65 -0
- package/external/folly/folly/chrono/Conv.h +712 -0
- package/external/folly/folly/chrono/test/BUCK +26 -0
- package/external/folly/folly/chrono/test/ClockTest.cpp +68 -0
- package/external/folly/folly/chrono/test/ConvTest.cpp +652 -0
- package/external/folly/folly/concurrency/AtomicSharedPtr.h +387 -0
- package/external/folly/folly/concurrency/BUCK +170 -0
- package/external/folly/folly/concurrency/CacheLocality.h +460 -0
- package/external/folly/folly/concurrency/ConcurrentHashMap.h +822 -0
- package/external/folly/folly/concurrency/CoreCachedSharedPtr.h +232 -0
- package/external/folly/folly/concurrency/DeadlockDetector.cpp +27 -0
- package/external/folly/folly/concurrency/DeadlockDetector.h +44 -0
- package/external/folly/folly/concurrency/DynamicBoundedQueue.h +751 -0
- package/external/folly/folly/concurrency/PriorityUnboundedQueueSet.h +207 -0
- package/external/folly/folly/concurrency/ProcessLocalUniqueId.cpp +46 -0
- package/external/folly/folly/concurrency/ProcessLocalUniqueId.h +38 -0
- package/external/folly/folly/concurrency/SingletonRelaxedCounter.h +325 -0
- package/external/folly/folly/concurrency/ThreadCachedSynchronized.h +227 -0
- package/external/folly/folly/concurrency/UnboundedQueue.h +891 -0
- package/external/folly/folly/concurrency/container/BUCK +77 -0
- package/external/folly/folly/concurrency/container/FlatCombiningPriorityQueue.h +426 -0
- package/external/folly/folly/concurrency/container/LockFreeRingBuffer.h +306 -0
- package/external/folly/folly/concurrency/container/RelaxedConcurrentPriorityQueue.h +1212 -0
- package/external/folly/folly/concurrency/container/SingleWriterFixedHashMap.h +322 -0
- package/external/folly/folly/concurrency/container/atomic_grow_array.h +564 -0
- package/external/folly/folly/concurrency/container/test/BUCK +75 -0
- package/external/folly/folly/concurrency/container/test/FlatCombiningPriorityQueueTest.cpp +570 -0
- package/external/folly/folly/concurrency/container/test/LockFreeRingBufferTest.cpp +276 -0
- package/external/folly/folly/concurrency/container/test/RelaxedConcurrentPriorityQueueTest.cpp +1570 -0
- package/external/folly/folly/concurrency/container/test/SingleWriterFixedHashMapTest.cpp +401 -0
- package/external/folly/folly/concurrency/container/test/atomic_grow_array_test.cpp +187 -0
- package/external/folly/folly/concurrency/detail/AtomicSharedPtr-detail.h +212 -0
- package/external/folly/folly/concurrency/detail/ConcurrentHashMap-detail.h +1911 -0
- package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.cpp +43 -0
- package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.h +190 -0
- package/external/folly/folly/concurrency/memory/BUCK +53 -0
- package/external/folly/folly/concurrency/memory/PrimaryPtr.h +338 -0
- package/external/folly/folly/concurrency/memory/ReadMostlySharedPtr.h +511 -0
- package/external/folly/folly/concurrency/memory/TLRefCount.h +228 -0
- package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrBenchmark.cpp +56 -0
- package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrTest.cpp +454 -0
- package/external/folly/folly/concurrency/memory/test/BUCK +95 -0
- package/external/folly/folly/concurrency/memory/test/PrimaryPtrTest.cpp +303 -0
- package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrBenchmark.cpp +138 -0
- package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrStressTest.cpp +75 -0
- package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrTest.cpp +378 -0
- package/external/folly/folly/concurrency/memory/test/RefCountBenchmark.cpp +90 -0
- package/external/folly/folly/concurrency/memory/test/RefCountTest.cpp +168 -0
- package/external/folly/folly/concurrency/test/AtomicSharedPtrCounted.h +156 -0
- package/external/folly/folly/concurrency/test/AtomicSharedPtrPerformance.cpp +255 -0
- package/external/folly/folly/concurrency/test/AtomicSharedPtrTest.cpp +257 -0
- package/external/folly/folly/concurrency/test/BUCK +229 -0
- package/external/folly/folly/concurrency/test/CacheLocalityBenchmark.cpp +392 -0
- package/external/folly/folly/concurrency/test/CacheLocalityTest.cpp +1229 -0
- package/external/folly/folly/concurrency/test/ConcurrentHashMapBench.cpp +260 -0
- package/external/folly/folly/concurrency/test/ConcurrentHashMapTest.cpp +1242 -0
- package/external/folly/folly/concurrency/test/CoreCachedSharedPtrTest.cpp +408 -0
- package/external/folly/folly/concurrency/test/DynamicBoundedQueueTest.cpp +984 -0
- package/external/folly/folly/concurrency/test/PriorityUnboundedQueueSetTest.cpp +73 -0
- package/external/folly/folly/concurrency/test/ProcessLocalUniqueIdTest.cpp +66 -0
- package/external/folly/folly/concurrency/test/SingletonRelaxedCounterBench.cpp +101 -0
- package/external/folly/folly/concurrency/test/SingletonRelaxedCounterTest.cpp +185 -0
- package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedBench.cpp +76 -0
- package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedTest.cpp +93 -0
- package/external/folly/folly/concurrency/test/UnboundedQueueTest.cpp +1302 -0
- package/external/folly/folly/container/Access.h +57 -0
- package/external/folly/folly/container/Array.h +87 -0
- package/external/folly/folly/container/BUCK +353 -0
- package/external/folly/folly/container/BitIterator.h +203 -0
- package/external/folly/folly/container/Enumerate.h +162 -0
- package/external/folly/folly/container/EvictingCacheMap.h +730 -0
- package/external/folly/folly/container/F14.md +300 -0
- package/external/folly/folly/container/F14Map-fwd.h +113 -0
- package/external/folly/folly/container/F14Map.h +2108 -0
- package/external/folly/folly/container/F14Set-fwd.h +95 -0
- package/external/folly/folly/container/F14Set.h +1603 -0
- package/external/folly/folly/container/FBVector.h +1711 -0
- package/external/folly/folly/container/Foreach-inl.h +316 -0
- package/external/folly/folly/container/Foreach.h +209 -0
- package/external/folly/folly/container/HeterogeneousAccess-fwd.h +33 -0
- package/external/folly/folly/container/HeterogeneousAccess.h +171 -0
- package/external/folly/folly/container/IntrusiveHeap.h +268 -0
- package/external/folly/folly/container/IntrusiveList.h +131 -0
- package/external/folly/folly/container/Iterator.h +843 -0
- package/external/folly/folly/container/MapUtil.h +376 -0
- package/external/folly/folly/container/Merge.h +90 -0
- package/external/folly/folly/container/RegexMatchCache.cpp +521 -0
- package/external/folly/folly/container/RegexMatchCache.h +699 -0
- package/external/folly/folly/container/Reserve.h +109 -0
- package/external/folly/folly/container/SparseByteSet.h +123 -0
- package/external/folly/folly/container/View.h +81 -0
- package/external/folly/folly/container/WeightedEvictingCacheMap.h +651 -0
- package/external/folly/folly/container/detail/BUCK +115 -0
- package/external/folly/folly/container/detail/BitIteratorDetail.h +87 -0
- package/external/folly/folly/container/detail/F14Defaults.h +34 -0
- package/external/folly/folly/container/detail/F14IntrinsicsAvailability.h +67 -0
- package/external/folly/folly/container/detail/F14MapFallback.h +717 -0
- package/external/folly/folly/container/detail/F14Mask.h +235 -0
- package/external/folly/folly/container/detail/F14Policy.h +1523 -0
- package/external/folly/folly/container/detail/F14SetFallback.h +528 -0
- package/external/folly/folly/container/detail/F14Table.cpp +71 -0
- package/external/folly/folly/container/detail/F14Table.h +2680 -0
- package/external/folly/folly/container/detail/Util.h +303 -0
- package/external/folly/folly/container/detail/tape_detail.h +135 -0
- package/external/folly/folly/container/detail/test/BUCK +14 -0
- package/external/folly/folly/container/detail/test/F14DetailTest.cpp +47 -0
- package/external/folly/folly/container/heap_vector_types.h +1683 -0
- package/external/folly/folly/container/range_traits.h +81 -0
- package/external/folly/folly/container/small_vector.h +1476 -0
- package/external/folly/folly/container/sorted_vector_types.h +1652 -0
- package/external/folly/folly/container/span.h +408 -0
- package/external/folly/folly/container/tape.h +608 -0
- package/external/folly/folly/container/test/.clang-tidy +12 -0
- package/external/folly/folly/container/test/AccessTest.cpp +138 -0
- package/external/folly/folly/container/test/ArrayTest.cpp +84 -0
- package/external/folly/folly/container/test/BUCK +568 -0
- package/external/folly/folly/container/test/BitIteratorBench.cpp +112 -0
- package/external/folly/folly/container/test/BitIteratorTest.cpp +109 -0
- package/external/folly/folly/container/test/EnumerateTest.cpp +294 -0
- package/external/folly/folly/container/test/EvictingCacheMapBench.cpp +80 -0
- package/external/folly/folly/container/test/EvictingCacheMapTest.cpp +842 -0
- package/external/folly/folly/container/test/F14AsanSupportTest.cpp +143 -0
- package/external/folly/folly/container/test/F14FwdTest.cpp +37 -0
- package/external/folly/folly/container/test/F14InterprocessTest.cpp +404 -0
- package/external/folly/folly/container/test/F14MapTest.cpp +2543 -0
- package/external/folly/folly/container/test/F14PolicyTest.cpp +49 -0
- package/external/folly/folly/container/test/F14SetTest.cpp +1738 -0
- package/external/folly/folly/container/test/F14SmallOverheads.cpp +215 -0
- package/external/folly/folly/container/test/F14TestUtil.h +117 -0
- package/external/folly/folly/container/test/FBVectorBenchmark.cpp +380 -0
- package/external/folly/folly/container/test/FBVectorBenchmarks.cpp.h +100 -0
- package/external/folly/folly/container/test/FBVectorTest.cpp +326 -0
- package/external/folly/folly/container/test/FBVectorTests.cpp.h +304 -0
- package/external/folly/folly/container/test/ForeachBenchmark.cpp +388 -0
- package/external/folly/folly/container/test/ForeachTest.cpp +338 -0
- package/external/folly/folly/container/test/HashMapsBench.cpp +458 -0
- package/external/folly/folly/container/test/HeterogeneousAccessTest.cpp +242 -0
- package/external/folly/folly/container/test/IntrusiveHeapTest.cpp +262 -0
- package/external/folly/folly/container/test/IteratorTest.cpp +989 -0
- package/external/folly/folly/container/test/MapUtilTest.cpp +365 -0
- package/external/folly/folly/container/test/MergeTest.cpp +66 -0
- package/external/folly/folly/container/test/RegexMatchCacheTest.cpp +634 -0
- package/external/folly/folly/container/test/ReserveTest.cpp +173 -0
- package/external/folly/folly/container/test/SparseByteSetBenchmark.cpp +153 -0
- package/external/folly/folly/container/test/SparseByteSetTest.cpp +117 -0
- package/external/folly/folly/container/test/TrackingTypes.h +584 -0
- package/external/folly/folly/container/test/UtilTest.cpp +609 -0
- package/external/folly/folly/container/test/WeightedEvictingCacheMapTest.cpp +800 -0
- package/external/folly/folly/container/test/heap_vector_types_test.cpp +1774 -0
- package/external/folly/folly/container/test/range_traits_test.cpp +59 -0
- package/external/folly/folly/container/test/small_vector_test.cpp +1571 -0
- package/external/folly/folly/container/test/sorted_vector_test.cpp +1589 -0
- package/external/folly/folly/container/test/span_test.cpp +520 -0
- package/external/folly/folly/container/test/tape_bench.cpp +200 -0
- package/external/folly/folly/container/test/tape_test.cpp +590 -0
- package/external/folly/folly/defs.bzl +238 -0
- package/external/folly/folly/detail/AsyncTrace.cpp +36 -0
- package/external/folly/folly/detail/AsyncTrace.h +44 -0
- package/external/folly/folly/detail/AtomicHashUtils.h +42 -0
- package/external/folly/folly/detail/AtomicUnorderedMapUtils.h +80 -0
- package/external/folly/folly/detail/BUCK +406 -0
- package/external/folly/folly/detail/DiscriminatedPtrDetail.h +172 -0
- package/external/folly/folly/detail/FileUtilDetail.cpp +63 -0
- package/external/folly/folly/detail/FileUtilDetail.h +85 -0
- package/external/folly/folly/detail/FileUtilVectorDetail.h +81 -0
- package/external/folly/folly/detail/FingerprintPolynomial.h +132 -0
- package/external/folly/folly/detail/Futex-inl.h +123 -0
- package/external/folly/folly/detail/Futex.cpp +273 -0
- package/external/folly/folly/detail/Futex.h +109 -0
- package/external/folly/folly/detail/GroupVarintDetail.h +101 -0
- package/external/folly/folly/detail/IPAddress.cpp +37 -0
- package/external/folly/folly/detail/IPAddress.h +57 -0
- package/external/folly/folly/detail/IPAddressSource.h +278 -0
- package/external/folly/folly/detail/Iterators.h +156 -0
- package/external/folly/folly/detail/MPMCPipelineDetail.h +122 -0
- package/external/folly/folly/detail/MemoryIdler.cpp +233 -0
- package/external/folly/folly/detail/MemoryIdler.h +216 -0
- package/external/folly/folly/detail/PerfScoped.cpp +112 -0
- package/external/folly/folly/detail/PerfScoped.h +70 -0
- package/external/folly/folly/detail/PolyDetail.h +921 -0
- package/external/folly/folly/detail/RangeCommon.cpp +55 -0
- package/external/folly/folly/detail/RangeCommon.h +93 -0
- package/external/folly/folly/detail/RangeSse42.cpp +198 -0
- package/external/folly/folly/detail/RangeSse42.h +30 -0
- package/external/folly/folly/detail/SimpleSimdStringUtils.cpp +31 -0
- package/external/folly/folly/detail/SimpleSimdStringUtils.h +27 -0
- package/external/folly/folly/detail/SimpleSimdStringUtilsImpl.h +63 -0
- package/external/folly/folly/detail/Singleton.h +34 -0
- package/external/folly/folly/detail/SlowFingerprint.h +90 -0
- package/external/folly/folly/detail/SocketFastOpen.cpp +175 -0
- package/external/folly/folly/detail/SocketFastOpen.h +89 -0
- package/external/folly/folly/detail/SplitStringSimd.cpp +84 -0
- package/external/folly/folly/detail/SplitStringSimd.h +151 -0
- package/external/folly/folly/detail/SplitStringSimdImpl.h +149 -0
- package/external/folly/folly/detail/Sse.cpp +35 -0
- package/external/folly/folly/detail/Sse.h +45 -0
- package/external/folly/folly/detail/StaticSingletonManager.cpp +119 -0
- package/external/folly/folly/detail/StaticSingletonManager.h +298 -0
- package/external/folly/folly/detail/ThreadLocalDetail.cpp +492 -0
- package/external/folly/folly/detail/ThreadLocalDetail.h +800 -0
- package/external/folly/folly/detail/TrapOnAvx512.cpp +41 -0
- package/external/folly/folly/detail/TrapOnAvx512.h +21 -0
- package/external/folly/folly/detail/TurnSequencer.h +295 -0
- package/external/folly/folly/detail/TypeList.h +551 -0
- package/external/folly/folly/detail/UniqueInstance.cpp +136 -0
- package/external/folly/folly/detail/UniqueInstance.h +68 -0
- package/external/folly/folly/detail/base64_detail/BUCK +102 -0
- package/external/folly/folly/detail/base64_detail/Base64Api.cpp +40 -0
- package/external/folly/folly/detail/base64_detail/Base64Api.h +101 -0
- package/external/folly/folly/detail/base64_detail/Base64Common.h +80 -0
- package/external/folly/folly/detail/base64_detail/Base64Constants.h +79 -0
- package/external/folly/folly/detail/base64_detail/Base64HiddenConstants.h +129 -0
- package/external/folly/folly/detail/base64_detail/Base64SWAR.cpp +161 -0
- package/external/folly/folly/detail/base64_detail/Base64SWAR.h +32 -0
- package/external/folly/folly/detail/base64_detail/Base64Scalar.h +262 -0
- package/external/folly/folly/detail/base64_detail/Base64Simd.h +102 -0
- package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.cpp +42 -0
- package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.h +33 -0
- package/external/folly/folly/detail/base64_detail/Base64_SSE4_2_Platform.h +167 -0
- package/external/folly/folly/detail/base64_detail/README.md +392 -0
- package/external/folly/folly/detail/base64_detail/tests/BUCK +36 -0
- package/external/folly/folly/detail/base64_detail/tests/Base64AgainstScalarTest.cpp +141 -0
- package/external/folly/folly/detail/base64_detail/tests/Base64PlatformTest.cpp +273 -0
- package/external/folly/folly/detail/base64_detail/tests/Base64SpecialCasesTest.cpp +555 -0
- package/external/folly/folly/detail/test/AsyncTraceTest.cpp +43 -0
- package/external/folly/folly/detail/test/BUCK +118 -0
- package/external/folly/folly/detail/test/FileUtilDetailTest.cpp +56 -0
- package/external/folly/folly/detail/test/PerfScopedTest.cpp +107 -0
- package/external/folly/folly/detail/test/SimpleSimdStringUtilsTest.cpp +92 -0
- package/external/folly/folly/detail/test/SplitStringSimdTest.cpp +242 -0
- package/external/folly/folly/detail/test/StaticSingletonManagerTest.cpp +121 -0
- package/external/folly/folly/detail/test/ThreadLocalBenchmark.cpp +116 -0
- package/external/folly/folly/detail/test/ThreadLocalDetailTest.cpp +194 -0
- package/external/folly/folly/detail/test/TrapOnAvx512TestNegative.cpp +29 -0
- package/external/folly/folly/detail/test/UniqueInstanceTest.cpp +60 -0
- package/external/folly/folly/detail/thread_local_globals.cpp +69 -0
- package/external/folly/folly/detail/thread_local_globals.h +36 -0
- package/external/folly/folly/docs/AtomicHashMap.md +134 -0
- package/external/folly/folly/docs/Benchmark.md +310 -0
- package/external/folly/folly/docs/Conv.md +291 -0
- package/external/folly/folly/docs/Dynamic.md +220 -0
- package/external/folly/folly/docs/DynamicConverter.md +71 -0
- package/external/folly/folly/docs/Executors.md +63 -0
- package/external/folly/folly/docs/FBString.md +46 -0
- package/external/folly/folly/docs/FBVector.md +200 -0
- package/external/folly/folly/docs/Fbvector--graphical_solutions.png +0 -0
- package/external/folly/folly/docs/Format.md +177 -0
- package/external/folly/folly/docs/Function.md +92 -0
- package/external/folly/folly/docs/Futures.md +263 -0
- package/external/folly/folly/docs/GroupVarint.md +46 -0
- package/external/folly/folly/docs/Histogram.md +104 -0
- package/external/folly/folly/docs/MapUtils.md +80 -0
- package/external/folly/folly/docs/Overview.md +263 -0
- package/external/folly/folly/docs/PackedSyncPtr.md +77 -0
- package/external/folly/folly/docs/Poly.md +500 -0
- package/external/folly/folly/docs/ProducerConsumerQueue.md +82 -0
- package/external/folly/folly/docs/Rcu.md +218 -0
- package/external/folly/folly/docs/SmallLocks.md +24 -0
- package/external/folly/folly/docs/Synchronized.md +793 -0
- package/external/folly/folly/docs/ThreadCachedInt.md +98 -0
- package/external/folly/folly/docs/ThreadLocal.md +105 -0
- package/external/folly/folly/docs/Traits.md +161 -0
- package/external/folly/folly/docs/small_vector.md +64 -0
- package/external/folly/folly/docs/style.css +23 -0
- package/external/folly/folly/dynamic-inl.h +17 -0
- package/external/folly/folly/dynamic.h +17 -0
- package/external/folly/folly/folly_extended_library.bzl +28 -0
- package/external/folly/folly/functional/ApplyTuple.h +204 -0
- package/external/folly/folly/functional/BUCK +57 -0
- package/external/folly/folly/functional/Invoke.h +880 -0
- package/external/folly/folly/functional/Partial.h +130 -0
- package/external/folly/folly/functional/protocol.h +203 -0
- package/external/folly/folly/functional/test/ApplyTupleTest.cpp +549 -0
- package/external/folly/folly/functional/test/BUCK +57 -0
- package/external/folly/folly/functional/test/InvokeTest.cpp +483 -0
- package/external/folly/folly/functional/test/PartialTest.cpp +141 -0
- package/external/folly/folly/functional/test/protocol_test.cpp +177 -0
- package/external/folly/folly/functional/test/traits_test.cpp +551 -0
- package/external/folly/folly/functional/traits.h +675 -0
- package/external/folly/folly/hash/BUCK +86 -0
- package/external/folly/folly/hash/Checksum.cpp +275 -0
- package/external/folly/folly/hash/Checksum.h +94 -0
- package/external/folly/folly/hash/FarmHash.h +46 -0
- package/external/folly/folly/hash/Hash.h +1045 -0
- package/external/folly/folly/hash/MurmurHash.h +86 -0
- package/external/folly/folly/hash/SpookyHashV1.cpp +391 -0
- package/external/folly/folly/hash/SpookyHashV1.h +307 -0
- package/external/folly/folly/hash/SpookyHashV2.cpp +392 -0
- package/external/folly/folly/hash/SpookyHashV2.h +339 -0
- package/external/folly/folly/hash/detail/BUCK +26 -0
- package/external/folly/folly/hash/detail/ChecksumDetail.cpp +296 -0
- package/external/folly/folly/hash/detail/ChecksumDetail.h +137 -0
- package/external/folly/folly/hash/detail/Crc32CombineDetail.cpp +191 -0
- package/external/folly/folly/hash/detail/Crc32cDetail.cpp +303 -0
- package/external/folly/folly/hash/test/BUCK +132 -0
- package/external/folly/folly/hash/test/ChecksumBenchmark.cpp +91 -0
- package/external/folly/folly/hash/test/ChecksumTest.cpp +587 -0
- package/external/folly/folly/hash/test/FarmHashTest.cpp +41 -0
- package/external/folly/folly/hash/test/HashBenchmark.cpp +238 -0
- package/external/folly/folly/hash/test/HashTest.cpp +997 -0
- package/external/folly/folly/hash/test/MurmurHashTest.cpp +76 -0
- package/external/folly/folly/hash/test/SpookyHashV1Test.cpp +559 -0
- package/external/folly/folly/hash/test/SpookyHashV2Test.cpp +549 -0
- package/external/folly/folly/hash/test/traits_test.cpp +69 -0
- package/external/folly/folly/hash/traits.h +115 -0
- package/external/folly/folly/json/BUCK +155 -0
- package/external/folly/folly/json/DynamicConverter.h +464 -0
- package/external/folly/folly/json/DynamicParser-inl.h +316 -0
- package/external/folly/folly/json/DynamicParser.cpp +198 -0
- package/external/folly/folly/json/DynamicParser.h +394 -0
- package/external/folly/folly/json/JSONSchema.cpp +1030 -0
- package/external/folly/folly/json/JSONSchema.h +73 -0
- package/external/folly/folly/json/JsonMockUtil.h +73 -0
- package/external/folly/folly/json/JsonTestUtil.cpp +167 -0
- package/external/folly/folly/json/JsonTestUtil.h +88 -0
- package/external/folly/folly/json/bser/BUCK +24 -0
- package/external/folly/folly/json/bser/Bser.h +107 -0
- package/external/folly/folly/json/bser/Dump.cpp +253 -0
- package/external/folly/folly/json/bser/Load.cpp +246 -0
- package/external/folly/folly/json/bser/test/BUCK +14 -0
- package/external/folly/folly/json/bser/test/BserTest.cpp +149 -0
- package/external/folly/folly/json/dynamic.cpp +552 -0
- package/external/folly/folly/json/dynamic.h +1346 -0
- package/external/folly/folly/json/json.h +238 -0
- package/external/folly/folly/json/json_patch.cpp +325 -0
- package/external/folly/folly/json/json_patch.h +126 -0
- package/external/folly/folly/json/json_pointer.cpp +114 -0
- package/external/folly/folly/json/json_pointer.h +87 -0
- package/external/folly/folly/json/test/BUCK +147 -0
- package/external/folly/folly/json/test/DynamicBenchmark.cpp +146 -0
- package/external/folly/folly/json/test/DynamicConverterTest.cpp +518 -0
- package/external/folly/folly/json/test/DynamicOtherTest.cpp +344 -0
- package/external/folly/folly/json/test/DynamicParserTest.cpp +443 -0
- package/external/folly/folly/json/test/DynamicTest.cpp +1647 -0
- package/external/folly/folly/json/test/JSONSchemaTest.cpp +450 -0
- package/external/folly/folly/json/test/JsonBenchmark.cpp +264 -0
- package/external/folly/folly/json/test/JsonOtherTest.cpp +51 -0
- package/external/folly/folly/json/test/JsonTest.cpp +1153 -0
- package/external/folly/folly/json/test/JsonTestUtilTest.cpp +97 -0
- package/external/folly/folly/json/test/json_patch_test.cpp +361 -0
- package/external/folly/folly/json/test/json_pointer_test.cpp +58 -0
- package/external/folly/folly/json/tool/BUCK +13 -0
- package/external/folly/folly/json/tool/JSONSchemaTester.cpp +58 -0
- package/external/folly/folly/json.h +17 -0
- package/external/folly/folly/json_patch.h +17 -0
- package/external/folly/folly/json_pointer.h +17 -0
- package/external/folly/folly/lang/Access.h +29 -0
- package/external/folly/folly/lang/Align.h +240 -0
- package/external/folly/folly/lang/Aligned.h +92 -0
- package/external/folly/folly/lang/Assume.h +82 -0
- package/external/folly/folly/lang/BUCK +287 -0
- package/external/folly/folly/lang/Badge.h +108 -0
- package/external/folly/folly/lang/Bits.h +570 -0
- package/external/folly/folly/lang/BitsClass.h +312 -0
- package/external/folly/folly/lang/Builtin.h +74 -0
- package/external/folly/folly/lang/CArray.h +34 -0
- package/external/folly/folly/lang/CString.cpp +86 -0
- package/external/folly/folly/lang/CString.h +55 -0
- package/external/folly/folly/lang/Cast.h +51 -0
- package/external/folly/folly/lang/CheckedMath.h +253 -0
- package/external/folly/folly/lang/CustomizationPoint.h +58 -0
- package/external/folly/folly/lang/Exception.cpp +822 -0
- package/external/folly/folly/lang/Exception.h +716 -0
- package/external/folly/folly/lang/Extern.h +55 -0
- package/external/folly/folly/lang/Hint-inl.h +144 -0
- package/external/folly/folly/lang/Hint.h +238 -0
- package/external/folly/folly/lang/Keep.h +98 -0
- package/external/folly/folly/lang/New.h +124 -0
- package/external/folly/folly/lang/Ordering.h +140 -0
- package/external/folly/folly/lang/Pretty.h +159 -0
- package/external/folly/folly/lang/PropagateConst.h +413 -0
- package/external/folly/folly/lang/RValueReferenceWrapper.h +152 -0
- package/external/folly/folly/lang/SafeAssert.cpp +589 -0
- package/external/folly/folly/lang/StaticConst.h +33 -0
- package/external/folly/folly/lang/Thunk.h +100 -0
- package/external/folly/folly/lang/TypeInfo.h +58 -0
- package/external/folly/folly/lang/UncaughtExceptions.cpp +17 -0
- package/external/folly/folly/lang/UncaughtExceptions.h +19 -0
- package/external/folly/folly/lang/test/AlignTest.cpp +87 -0
- package/external/folly/folly/lang/test/AlignedTest.cpp +130 -0
- package/external/folly/folly/lang/test/BUCK +258 -0
- package/external/folly/folly/lang/test/BadgeTest.cpp +89 -0
- package/external/folly/folly/lang/test/BitsBenchmark.cpp +164 -0
- package/external/folly/folly/lang/test/BitsClassBenchmark.cpp +122 -0
- package/external/folly/folly/lang/test/BitsClassTest.cpp +379 -0
- package/external/folly/folly/lang/test/BitsTest.cpp +577 -0
- package/external/folly/folly/lang/test/CStringTest.cpp +60 -0
- package/external/folly/folly/lang/test/CastTest.cpp +47 -0
- package/external/folly/folly/lang/test/CheckedMathTest.cpp +394 -0
- package/external/folly/folly/lang/test/ExceptionBench.cpp +427 -0
- package/external/folly/folly/lang/test/ExceptionTest.cpp +413 -0
- package/external/folly/folly/lang/test/ExternTest.cpp +39 -0
- package/external/folly/folly/lang/test/HintTest.cpp +100 -0
- package/external/folly/folly/lang/test/NewTest.cpp +38 -0
- package/external/folly/folly/lang/test/OrderingTest.cpp +105 -0
- package/external/folly/folly/lang/test/PrettyTest.cpp +44 -0
- package/external/folly/folly/lang/test/PropagateConstTest.cpp +356 -0
- package/external/folly/folly/lang/test/RValueReferenceWrapperTest.cpp +85 -0
- package/external/folly/folly/lang/test/SafeAssertTest.cpp +75 -0
- package/external/folly/folly/lang/test/ThunkTest.cpp +105 -0
- package/external/folly/folly/lang/test/ToAsciiBench.cpp +466 -0
- package/external/folly/folly/lang/test/ToAsciiTest.cpp +266 -0
- package/external/folly/folly/lang/test/TypeInfoTest.cpp +56 -0
- package/external/folly/folly/memcpy.S +292 -0
- package/external/folly/folly/memcpy_select_aarch64.cpp +145 -0
- package/external/folly/folly/memory/Arena-inl.h +83 -0
- package/external/folly/folly/memory/Arena.h +325 -0
- package/external/folly/folly/memory/BUCK +191 -0
- package/external/folly/folly/memory/JemallocHugePageAllocator.cpp +449 -0
- package/external/folly/folly/memory/JemallocHugePageAllocator.h +105 -0
- package/external/folly/folly/memory/JemallocHugePageAllocatorTest.cpp +341 -0
- package/external/folly/folly/memory/JemallocNodumpAllocator.cpp +176 -0
- package/external/folly/folly/memory/JemallocNodumpAllocator.h +119 -0
- package/external/folly/folly/memory/JemallocNodumpAllocatorTest.cpp +61 -0
- package/external/folly/folly/memory/MallctlHelper.cpp +37 -0
- package/external/folly/folly/memory/MallctlHelper.h +167 -0
- package/external/folly/folly/memory/Malloc.h +551 -0
- package/external/folly/folly/memory/MemoryResource.h +57 -0
- package/external/folly/folly/memory/ReentrantAllocator.cpp +162 -0
- package/external/folly/folly/memory/ReentrantAllocator.h +261 -0
- package/external/folly/folly/memory/SanitizeAddress.cpp +75 -0
- package/external/folly/folly/memory/SanitizeAddress.h +117 -0
- package/external/folly/folly/memory/SanitizeLeak.cpp +119 -0
- package/external/folly/folly/memory/SanitizeLeak.h +108 -0
- package/external/folly/folly/memory/ThreadCachedArena.cpp +53 -0
- package/external/folly/folly/memory/ThreadCachedArena.h +90 -0
- package/external/folly/folly/memory/UninitializedMemoryHacks.h +426 -0
- package/external/folly/folly/memory/detail/BUCK +10 -0
- package/external/folly/folly/memory/detail/MallocImpl.cpp +52 -0
- package/external/folly/folly/memory/detail/MallocImpl.h +97 -0
- package/external/folly/folly/memory/not_null-inl.h +522 -0
- package/external/folly/folly/memory/not_null.h +449 -0
- package/external/folly/folly/memory/test/ArenaTest.cpp +354 -0
- package/external/folly/folly/memory/test/BUCK +146 -0
- package/external/folly/folly/memory/test/MallctlHelperTest.cpp +169 -0
- package/external/folly/folly/memory/test/MallocBenchmark.cpp +91 -0
- package/external/folly/folly/memory/test/MallocTest.cpp +78 -0
- package/external/folly/folly/memory/test/MemoryResourceTest.cpp +31 -0
- package/external/folly/folly/memory/test/ReentrantAllocatorTest.cpp +144 -0
- package/external/folly/folly/memory/test/SanitizeAddressTest.cpp +67 -0
- package/external/folly/folly/memory/test/SanitizeLeakTest.cpp +139 -0
- package/external/folly/folly/memory/test/ThreadCachedArenaTest.cpp +276 -0
- package/external/folly/folly/memory/test/UninitializedMemoryHacksODR.cpp +21 -0
- package/external/folly/folly/memory/test/UninitializedMemoryHacksTest.cpp +327 -0
- package/external/folly/folly/memory/test/not_null_test.cpp +608 -0
- package/external/folly/folly/memset.S +245 -0
- package/external/folly/folly/memset_select_aarch64.cpp +72 -0
- package/external/folly/folly/portability/Asm.h +50 -0
- package/external/folly/folly/portability/Atomic.h +31 -0
- package/external/folly/folly/portability/BUCK +456 -0
- package/external/folly/folly/portability/Builtins.cpp +31 -0
- package/external/folly/folly/portability/Builtins.h +161 -0
- package/external/folly/folly/portability/Config.h +43 -0
- package/external/folly/folly/portability/Constexpr.h +145 -0
- package/external/folly/folly/portability/Dirent.cpp +140 -0
- package/external/folly/folly/portability/Dirent.h +41 -0
- package/external/folly/folly/portability/Event.h +44 -0
- package/external/folly/folly/portability/Fcntl.cpp +120 -0
- package/external/folly/folly/portability/Fcntl.h +67 -0
- package/external/folly/folly/portability/Filesystem.cpp +67 -0
- package/external/folly/folly/portability/Filesystem.h +114 -0
- package/external/folly/folly/portability/FmtCompile.h +40 -0
- package/external/folly/folly/portability/GFlags.h +139 -0
- package/external/folly/folly/portability/GMock.h +35 -0
- package/external/folly/folly/portability/GTest.h +35 -0
- package/external/folly/folly/portability/IOVec.h +34 -0
- package/external/folly/folly/portability/Libgen.cpp +59 -0
- package/external/folly/folly/portability/Libgen.h +29 -0
- package/external/folly/folly/portability/Libunwind.h +21 -0
- package/external/folly/folly/portability/Malloc.cpp +31 -0
- package/external/folly/folly/portability/Malloc.h +53 -0
- package/external/folly/folly/portability/Math.h +90 -0
- package/external/folly/folly/portability/Memory.h +26 -0
- package/external/folly/folly/portability/OpenSSL.cpp +17 -0
- package/external/folly/folly/portability/OpenSSL.h +102 -0
- package/external/folly/folly/portability/PThread.cpp +697 -0
- package/external/folly/folly/portability/PThread.h +148 -0
- package/external/folly/folly/portability/README.md +21 -0
- package/external/folly/folly/portability/Sched.cpp +41 -0
- package/external/folly/folly/portability/Sched.h +45 -0
- package/external/folly/folly/portability/Sockets.cpp +245 -0
- package/external/folly/folly/portability/Sockets.h +155 -0
- package/external/folly/folly/portability/SourceLocation.h +49 -0
- package/external/folly/folly/portability/Stdio.cpp +77 -0
- package/external/folly/folly/portability/Stdio.h +32 -0
- package/external/folly/folly/portability/Stdlib.cpp +172 -0
- package/external/folly/folly/portability/Stdlib.h +64 -0
- package/external/folly/folly/portability/String.cpp +53 -0
- package/external/folly/folly/portability/String.h +39 -0
- package/external/folly/folly/portability/SysFile.cpp +46 -0
- package/external/folly/folly/portability/SysFile.h +27 -0
- package/external/folly/folly/portability/SysMembarrier.cpp +104 -0
- package/external/folly/folly/portability/SysMembarrier.h +26 -0
- package/external/folly/folly/portability/SysMman.cpp +242 -0
- package/external/folly/folly/portability/SysMman.h +68 -0
- package/external/folly/folly/portability/SysResource.cpp +108 -0
- package/external/folly/folly/portability/SysResource.h +71 -0
- package/external/folly/folly/portability/SysStat.cpp +66 -0
- package/external/folly/folly/portability/SysStat.h +52 -0
- package/external/folly/folly/portability/SysSyscall.h +73 -0
- package/external/folly/folly/portability/SysTime.cpp +62 -0
- package/external/folly/folly/portability/SysTime.h +50 -0
- package/external/folly/folly/portability/SysTypes.h +44 -0
- package/external/folly/folly/portability/SysUio.cpp +179 -0
- package/external/folly/folly/portability/SysUio.h +51 -0
- package/external/folly/folly/portability/Syslog.h +39 -0
- package/external/folly/folly/portability/Time.cpp +357 -0
- package/external/folly/folly/portability/Time.h +74 -0
- package/external/folly/folly/portability/Unistd.h +111 -0
- package/external/folly/folly/portability/Windows.h +108 -0
- package/external/folly/folly/portability/openat2.c +30 -0
- package/external/folly/folly/portability/openat2.h +39 -0
- package/external/folly/folly/portability/test/BUCK +59 -0
- package/external/folly/folly/portability/test/ConstexprTest.cpp +102 -0
- package/external/folly/folly/portability/test/FilesystemTest.cpp +35 -0
- package/external/folly/folly/portability/test/LibgenTest.cpp +35 -0
- package/external/folly/folly/portability/test/OpenSSLPortabilityTest.cpp +108 -0
- package/external/folly/folly/portability/test/PThreadTest.cpp +80 -0
- package/external/folly/folly/portability/test/TimeTest.cpp +90 -0
- package/external/folly/folly/small_vector.h +17 -0
- package/external/folly/folly/somerge_defs.bzl +399 -0
- package/external/folly/folly/sorted_vector_types.h +17 -0
- package/external/folly/folly/stop_watch.h +317 -0
- package/external/folly/folly/synchronization/AsymmetricThreadFence.cpp +91 -0
- package/external/folly/folly/synchronization/AsymmetricThreadFence.h +60 -0
- package/external/folly/folly/synchronization/AtomicNotification-inl.h +146 -0
- package/external/folly/folly/synchronization/AtomicNotification.cpp +34 -0
- package/external/folly/folly/synchronization/AtomicNotification.h +117 -0
- package/external/folly/folly/synchronization/AtomicRef.h +181 -0
- package/external/folly/folly/synchronization/AtomicStruct.h +150 -0
- package/external/folly/folly/synchronization/AtomicUtil-inl.h +482 -0
- package/external/folly/folly/synchronization/AtomicUtil.h +179 -0
- package/external/folly/folly/synchronization/BUCK +418 -0
- package/external/folly/folly/synchronization/Baton.h +419 -0
- package/external/folly/folly/synchronization/CallOnce.h +263 -0
- package/external/folly/folly/synchronization/DelayedInit.h +179 -0
- package/external/folly/folly/synchronization/DistributedMutex-inl.h +1744 -0
- package/external/folly/folly/synchronization/DistributedMutex.cpp +27 -0
- package/external/folly/folly/synchronization/DistributedMutex.h +342 -0
- package/external/folly/folly/synchronization/EventCount.h +200 -0
- package/external/folly/folly/synchronization/FlatCombining.h +629 -0
- package/external/folly/folly/synchronization/Hazptr-fwd.h +217 -0
- package/external/folly/folly/synchronization/Hazptr.cpp +36 -0
- package/external/folly/folly/synchronization/Hazptr.h +209 -0
- package/external/folly/folly/synchronization/HazptrDomain.cpp +68 -0
- package/external/folly/folly/synchronization/HazptrDomain.h +832 -0
- package/external/folly/folly/synchronization/HazptrHolder.h +431 -0
- package/external/folly/folly/synchronization/HazptrObj.h +533 -0
- package/external/folly/folly/synchronization/HazptrObjLinked.h +315 -0
- package/external/folly/folly/synchronization/HazptrRec.h +68 -0
- package/external/folly/folly/synchronization/HazptrThrLocal.h +180 -0
- package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.cpp +46 -0
- package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.h +25 -0
- package/external/folly/folly/synchronization/Latch.h +160 -0
- package/external/folly/folly/synchronization/LifoSem.h +767 -0
- package/external/folly/folly/synchronization/Lock.h +887 -0
- package/external/folly/folly/synchronization/MicroSpinLock.h +154 -0
- package/external/folly/folly/synchronization/NativeSemaphore.h +187 -0
- package/external/folly/folly/synchronization/ParkingLot.cpp +37 -0
- package/external/folly/folly/synchronization/ParkingLot.h +330 -0
- package/external/folly/folly/synchronization/PicoSpinLock.h +167 -0
- package/external/folly/folly/synchronization/RWSpinLock.h +549 -0
- package/external/folly/folly/synchronization/Rcu.cpp +26 -0
- package/external/folly/folly/synchronization/Rcu.h +553 -0
- package/external/folly/folly/synchronization/RelaxedAtomic.h +336 -0
- package/external/folly/folly/synchronization/SanitizeThread.cpp +141 -0
- package/external/folly/folly/synchronization/SanitizeThread.h +166 -0
- package/external/folly/folly/synchronization/SaturatingSemaphore.h +324 -0
- package/external/folly/folly/synchronization/SmallLocks.h +36 -0
- package/external/folly/folly/synchronization/ThrottledLifoSem.h +362 -0
- package/external/folly/folly/synchronization/WaitOptions.cpp +25 -0
- package/external/folly/folly/synchronization/WaitOptions.h +75 -0
- package/external/folly/folly/synchronization/detail/AtomicUtils.h +59 -0
- package/external/folly/folly/synchronization/detail/BUCK +104 -0
- package/external/folly/folly/synchronization/detail/Hardware.cpp +192 -0
- package/external/folly/folly/synchronization/detail/Hardware.h +75 -0
- package/external/folly/folly/synchronization/detail/HazptrUtils.h +339 -0
- package/external/folly/folly/synchronization/detail/InlineFunctionRef.h +229 -0
- package/external/folly/folly/synchronization/detail/Sleeper.cpp +27 -0
- package/external/folly/folly/synchronization/detail/Sleeper.h +62 -0
- package/external/folly/folly/synchronization/detail/Spin.h +96 -0
- package/external/folly/folly/synchronization/detail/ThreadCachedLists.h +174 -0
- package/external/folly/folly/synchronization/detail/ThreadCachedReaders.h +189 -0
- package/external/folly/folly/synchronization/detail/ThreadCachedTag.h +26 -0
- package/external/folly/folly/synchronization/detail/test/BUCK +28 -0
- package/external/folly/folly/synchronization/detail/test/HardwareTest.cpp +74 -0
- package/external/folly/folly/synchronization/detail/test/InlineFunctionRefTest.cpp +286 -0
- package/external/folly/folly/synchronization/example/BUCK +27 -0
- package/external/folly/folly/synchronization/example/HazptrLockFreeLIFO.h +88 -0
- package/external/folly/folly/synchronization/example/HazptrSWMRSet.h +133 -0
- package/external/folly/folly/synchronization/example/HazptrWideCAS.h +62 -0
- package/external/folly/folly/synchronization/test/AtomicNotificationTest.cpp +236 -0
- package/external/folly/folly/synchronization/test/AtomicRefTest.cpp +170 -0
- package/external/folly/folly/synchronization/test/AtomicStructTest.cpp +65 -0
- package/external/folly/folly/synchronization/test/AtomicUtilBench.cpp +457 -0
- package/external/folly/folly/synchronization/test/AtomicUtilTest.cpp +650 -0
- package/external/folly/folly/synchronization/test/BUCK +495 -0
- package/external/folly/folly/synchronization/test/Barrier.h +52 -0
- package/external/folly/folly/synchronization/test/BarrierTest.cpp +56 -0
- package/external/folly/folly/synchronization/test/BatonBenchmark.cpp +77 -0
- package/external/folly/folly/synchronization/test/BatonTest.cpp +164 -0
- package/external/folly/folly/synchronization/test/BatonTestHelpers.h +118 -0
- package/external/folly/folly/synchronization/test/CallOnceBenchmark.cpp +72 -0
- package/external/folly/folly/synchronization/test/CallOnceTest.cpp +153 -0
- package/external/folly/folly/synchronization/test/DelayedInitTest.cpp +281 -0
- package/external/folly/folly/synchronization/test/DistributedMutexTest.cpp +2074 -0
- package/external/folly/folly/synchronization/test/EventCountTest.cpp +124 -0
- package/external/folly/folly/synchronization/test/FlatCombiningBenchmark.cpp +1789 -0
- package/external/folly/folly/synchronization/test/FlatCombiningExamples.h +222 -0
- package/external/folly/folly/synchronization/test/FlatCombiningTest.cpp +121 -0
- package/external/folly/folly/synchronization/test/FlatCombiningTestHelpers.h +227 -0
- package/external/folly/folly/synchronization/test/HazptrTest.cpp +1689 -0
- package/external/folly/folly/synchronization/test/LatchTest.cpp +224 -0
- package/external/folly/folly/synchronization/test/LifoSemBench.cpp +185 -0
- package/external/folly/folly/synchronization/test/LifoSemTests.cpp +353 -0
- package/external/folly/folly/synchronization/test/LockTest.cpp +1239 -0
- package/external/folly/folly/synchronization/test/NativeSemaphoreTest.cpp +37 -0
- package/external/folly/folly/synchronization/test/ParkingLotBenchmark.cpp +239 -0
- package/external/folly/folly/synchronization/test/ParkingLotTest.cpp +170 -0
- package/external/folly/folly/synchronization/test/RWSpinLockTest.cpp +235 -0
- package/external/folly/folly/synchronization/test/RcuBench.cpp +66 -0
- package/external/folly/folly/synchronization/test/RcuTest.cpp +330 -0
- package/external/folly/folly/synchronization/test/RelaxedAtomicTest.cpp +389 -0
- package/external/folly/folly/synchronization/test/SaturatingSemaphoreTest.cpp +166 -0
- package/external/folly/folly/synchronization/test/Semaphore.h +242 -0
- package/external/folly/folly/synchronization/test/SemaphoreTest.cpp +271 -0
- package/external/folly/folly/synchronization/test/SmallLocksBenchmark.cpp +1296 -0
- package/external/folly/folly/synchronization/test/SmallLocksTest.cpp +510 -0
- package/external/folly/folly/synchronization/test/ThreadCachedEpochBench.h +67 -0
- package/external/folly/folly/synchronization/test/ThreadCachedReadersBench.cpp +42 -0
- package/external/folly/folly/synchronization/test/ThreadCachedReadersTest.cpp +52 -0
- package/external/folly/folly/synchronization/test/ThrottledLifoSemTest.cpp +243 -0
- package/external/folly/folly/system/AtFork.cpp +205 -0
- package/external/folly/folly/system/AtFork.h +116 -0
- package/external/folly/folly/system/AuxVector.h +198 -0
- package/external/folly/folly/system/BUCK +144 -0
- package/external/folly/folly/system/EnvUtil.cpp +93 -0
- package/external/folly/folly/system/EnvUtil.h +113 -0
- package/external/folly/folly/system/HardwareConcurrency.cpp +39 -0
- package/external/folly/folly/system/HardwareConcurrency.h +23 -0
- package/external/folly/folly/system/MemoryMapping.cpp +477 -0
- package/external/folly/folly/system/MemoryMapping.h +287 -0
- package/external/folly/folly/system/Pid.cpp +87 -0
- package/external/folly/folly/system/Pid.h +34 -0
- package/external/folly/folly/system/Shell.cpp +33 -0
- package/external/folly/folly/system/Shell.h +93 -0
- package/external/folly/folly/system/ThreadId.cpp +89 -0
- package/external/folly/folly/system/ThreadId.h +62 -0
- package/external/folly/folly/system/ThreadName.cpp +330 -0
- package/external/folly/folly/system/ThreadName.h +72 -0
- package/external/folly/folly/system/test/AtForkTest.cpp +309 -0
- package/external/folly/folly/system/test/AuxVectorTest.cpp +55 -0
- package/external/folly/folly/system/test/BUCK +120 -0
- package/external/folly/folly/system/test/EnvUtilSubprocess.cpp +26 -0
- package/external/folly/folly/system/test/EnvUtilTest.cpp +197 -0
- package/external/folly/folly/system/test/MemoryMappingTest.cpp +179 -0
- package/external/folly/folly/system/test/PidTest.cpp +46 -0
- package/external/folly/folly/system/test/ShellTest.cpp +66 -0
- package/external/folly/folly/system/test/ThreadIdTest.cpp +114 -0
- package/external/folly/folly/system/test/ThreadNameTest.cpp +85 -0
- package/external/folly/folly.vcxitems +164 -0
- package/external/folly/static/logo.svg +1 -0
- package/external/folly/sync-config.json +8 -0
- package/just-task.js +13 -2
- package/package.json +6 -6
- package/template/cpp-lib/proj/MyLib.sln +0 -33
- package/template/cs-lib/proj/MyLib.sln +0 -33
- package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +1 -1
- package/templates/cpp-app/windows/MyApp.sln +0 -33
- package/templates/cpp-lib/example/metro.config.js +30 -4
- package/templates/cpp-lib/windows/MyLib/MyLib.vcxproj +1 -1
- package/templates/cpp-lib/windows/MyLib.sln +0 -33
- package/Folly/Folly.vcxproj +0 -376
- package/Folly/Folly.vcxproj.filters +0 -558
- package/fmt/fmt.vcxproj +0 -153
- package/fmt/fmt.vcxproj.filters +0 -59
- package/fmt/pch.cpp +0 -4
- package/fmt/pch.h +0 -2
- /package/{fmt → external/fmt}/cgmanifest.json +0 -0
- /package/{Folly → external/folly}/Folly.natvis +0 -0
- /package/{Folly → external/folly}/cgmanifest.json +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/ConstexprMath.h +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/Conv.cpp +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/chrono/Hardware.h +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/concurrency/CacheLocality.cpp +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/dynamic-inl.h +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/json.cpp +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/SafeAssert.h +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.cpp +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.h +0 -0
- /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/portability/Unistd.cpp +0 -0
|
@@ -0,0 +1,1833 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// Docs: https://fburl.com/fbcref_synchronized
|
|
19
|
+
//
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This module implements a Synchronized abstraction useful in
|
|
23
|
+
* mutex-based concurrency.
|
|
24
|
+
*
|
|
25
|
+
* The Synchronized<T, Mutex> class is the primary public API exposed by this
|
|
26
|
+
* module. See folly/docs/Synchronized.md for a more complete explanation of
|
|
27
|
+
* this class and its benefits.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
#pragma once
|
|
31
|
+
|
|
32
|
+
#include <folly/Function.h>
|
|
33
|
+
#include <folly/Likely.h>
|
|
34
|
+
#include <folly/Preprocessor.h>
|
|
35
|
+
#include <folly/SharedMutex.h>
|
|
36
|
+
#include <folly/Traits.h>
|
|
37
|
+
#include <folly/Utility.h>
|
|
38
|
+
#include <folly/container/Foreach.h>
|
|
39
|
+
#include <folly/functional/ApplyTuple.h>
|
|
40
|
+
#include <folly/synchronization/Lock.h>
|
|
41
|
+
|
|
42
|
+
#include <glog/logging.h>
|
|
43
|
+
|
|
44
|
+
#include <array>
|
|
45
|
+
#include <mutex>
|
|
46
|
+
#include <tuple>
|
|
47
|
+
#include <type_traits>
|
|
48
|
+
#include <utility>
|
|
49
|
+
|
|
50
|
+
namespace folly {
|
|
51
|
+
|
|
52
|
+
namespace detail {
|
|
53
|
+
|
|
54
|
+
template <typename, typename Mutex>
|
|
55
|
+
inline constexpr bool kSynchronizedMutexIsUnique = false;
|
|
56
|
+
template <typename Mutex>
|
|
57
|
+
inline constexpr bool kSynchronizedMutexIsUnique<
|
|
58
|
+
decltype(void(std::declval<Mutex&>().lock())),
|
|
59
|
+
Mutex> = true;
|
|
60
|
+
|
|
61
|
+
template <typename, typename Mutex>
|
|
62
|
+
inline constexpr bool kSynchronizedMutexIsShared = false;
|
|
63
|
+
template <typename Mutex>
|
|
64
|
+
inline constexpr bool kSynchronizedMutexIsShared<
|
|
65
|
+
decltype(void(std::declval<Mutex&>().lock_shared())),
|
|
66
|
+
Mutex> = true;
|
|
67
|
+
|
|
68
|
+
template <typename, typename Mutex>
|
|
69
|
+
inline constexpr bool kSynchronizedMutexIsUpgrade = false;
|
|
70
|
+
template <typename Mutex>
|
|
71
|
+
inline constexpr bool kSynchronizedMutexIsUpgrade<
|
|
72
|
+
decltype(void(std::declval<Mutex&>().lock_upgrade())),
|
|
73
|
+
Mutex> = true;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* An enum to describe the "level" of a mutex. The supported levels are
|
|
77
|
+
* Unique - a normal mutex that supports only exclusive locking
|
|
78
|
+
* Shared - a shared mutex which has shared locking and unlocking functions;
|
|
79
|
+
* Upgrade - a mutex that has all the methods of the two above along with
|
|
80
|
+
* support for upgradable locking
|
|
81
|
+
*/
|
|
82
|
+
enum class SynchronizedMutexLevel { Unknown, Unique, Shared, Upgrade };
|
|
83
|
+
|
|
84
|
+
template <typename Mutex>
|
|
85
|
+
inline constexpr SynchronizedMutexLevel kSynchronizedMutexLevel =
|
|
86
|
+
kSynchronizedMutexIsUpgrade<void, Mutex> ? SynchronizedMutexLevel::Upgrade
|
|
87
|
+
: kSynchronizedMutexIsShared<void, Mutex> ? SynchronizedMutexLevel::Shared
|
|
88
|
+
: kSynchronizedMutexIsUnique<void, Mutex> ? SynchronizedMutexLevel::Unique
|
|
89
|
+
: SynchronizedMutexLevel::Unknown;
|
|
90
|
+
|
|
91
|
+
enum class SynchronizedMutexMethod { Lock, TryLock };
|
|
92
|
+
|
|
93
|
+
template <SynchronizedMutexLevel Level, SynchronizedMutexMethod Method>
|
|
94
|
+
struct SynchronizedLockPolicy {
|
|
95
|
+
static constexpr SynchronizedMutexLevel level = Level;
|
|
96
|
+
static constexpr SynchronizedMutexMethod method = Method;
|
|
97
|
+
};
|
|
98
|
+
using SynchronizedLockPolicyExclusive = SynchronizedLockPolicy<
|
|
99
|
+
SynchronizedMutexLevel::Unique,
|
|
100
|
+
SynchronizedMutexMethod::Lock>;
|
|
101
|
+
using SynchronizedLockPolicyTryExclusive = SynchronizedLockPolicy<
|
|
102
|
+
SynchronizedMutexLevel::Unique,
|
|
103
|
+
SynchronizedMutexMethod::TryLock>;
|
|
104
|
+
using SynchronizedLockPolicyShared = SynchronizedLockPolicy<
|
|
105
|
+
SynchronizedMutexLevel::Shared,
|
|
106
|
+
SynchronizedMutexMethod::Lock>;
|
|
107
|
+
using SynchronizedLockPolicyTryShared = SynchronizedLockPolicy<
|
|
108
|
+
SynchronizedMutexLevel::Shared,
|
|
109
|
+
SynchronizedMutexMethod::TryLock>;
|
|
110
|
+
using SynchronizedLockPolicyUpgrade = SynchronizedLockPolicy<
|
|
111
|
+
SynchronizedMutexLevel::Upgrade,
|
|
112
|
+
SynchronizedMutexMethod::Lock>;
|
|
113
|
+
using SynchronizedLockPolicyTryUpgrade = SynchronizedLockPolicy<
|
|
114
|
+
SynchronizedMutexLevel::Upgrade,
|
|
115
|
+
SynchronizedMutexMethod::TryLock>;
|
|
116
|
+
|
|
117
|
+
template <SynchronizedMutexLevel>
|
|
118
|
+
struct SynchronizedLockType_ {};
|
|
119
|
+
template <>
|
|
120
|
+
struct SynchronizedLockType_<SynchronizedMutexLevel::Unique> {
|
|
121
|
+
template <typename Mutex>
|
|
122
|
+
using apply = std::unique_lock<Mutex>;
|
|
123
|
+
};
|
|
124
|
+
template <>
|
|
125
|
+
struct SynchronizedLockType_<SynchronizedMutexLevel::Shared> {
|
|
126
|
+
template <typename Mutex>
|
|
127
|
+
using apply = std::shared_lock<Mutex>;
|
|
128
|
+
};
|
|
129
|
+
template <>
|
|
130
|
+
struct SynchronizedLockType_<SynchronizedMutexLevel::Upgrade> {
|
|
131
|
+
template <typename Mutex>
|
|
132
|
+
using apply = upgrade_lock<Mutex>;
|
|
133
|
+
};
|
|
134
|
+
template <SynchronizedMutexLevel Level, typename MutexType>
|
|
135
|
+
using SynchronizedLockType =
|
|
136
|
+
typename SynchronizedLockType_<Level>::template apply<MutexType>;
|
|
137
|
+
|
|
138
|
+
} // namespace detail
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* SynchronizedBase is a helper parent class for Synchronized<T>.
|
|
142
|
+
*
|
|
143
|
+
* It provides wlock() and rlock() methods for shared mutex types,
|
|
144
|
+
* or lock() methods for purely exclusive mutex types.
|
|
145
|
+
*/
|
|
146
|
+
template <class Subclass, detail::SynchronizedMutexLevel level>
|
|
147
|
+
class SynchronizedBase;
|
|
148
|
+
|
|
149
|
+
template <class LockedType, class Mutex, class LockPolicy>
|
|
150
|
+
class LockedPtrBase;
|
|
151
|
+
template <class LockedType, class LockPolicy>
|
|
152
|
+
class LockedPtr;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* SynchronizedBase specialization for shared mutex types.
|
|
156
|
+
*
|
|
157
|
+
* This class provides wlock() and rlock() methods for acquiring the lock and
|
|
158
|
+
* accessing the data.
|
|
159
|
+
*/
|
|
160
|
+
template <class Subclass>
|
|
161
|
+
class SynchronizedBase<Subclass, detail::SynchronizedMutexLevel::Shared> {
|
|
162
|
+
private:
|
|
163
|
+
template <typename T, typename P>
|
|
164
|
+
using LockedPtr_ = ::folly::LockedPtr<T, P>;
|
|
165
|
+
|
|
166
|
+
public:
|
|
167
|
+
using LockPolicyExclusive = detail::SynchronizedLockPolicyExclusive;
|
|
168
|
+
using LockPolicyShared = detail::SynchronizedLockPolicyShared;
|
|
169
|
+
using LockPolicyTryExclusive = detail::SynchronizedLockPolicyTryExclusive;
|
|
170
|
+
using LockPolicyTryShared = detail::SynchronizedLockPolicyTryShared;
|
|
171
|
+
|
|
172
|
+
using WLockedPtr = LockedPtr_<Subclass, LockPolicyExclusive>;
|
|
173
|
+
using ConstWLockedPtr = LockedPtr_<const Subclass, LockPolicyExclusive>;
|
|
174
|
+
|
|
175
|
+
using RLockedPtr = LockedPtr_<Subclass, LockPolicyShared>;
|
|
176
|
+
using ConstRLockedPtr = LockedPtr_<const Subclass, LockPolicyShared>;
|
|
177
|
+
|
|
178
|
+
using TryWLockedPtr = LockedPtr_<Subclass, LockPolicyTryExclusive>;
|
|
179
|
+
using ConstTryWLockedPtr = LockedPtr_<const Subclass, LockPolicyTryExclusive>;
|
|
180
|
+
|
|
181
|
+
using TryRLockedPtr = LockedPtr_<Subclass, LockPolicyTryShared>;
|
|
182
|
+
using ConstTryRLockedPtr = LockedPtr_<const Subclass, LockPolicyTryShared>;
|
|
183
|
+
|
|
184
|
+
// These aliases are deprecated.
|
|
185
|
+
// TODO: Codemod them away.
|
|
186
|
+
using LockedPtr = WLockedPtr;
|
|
187
|
+
using ConstLockedPtr = ConstRLockedPtr;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @brief Acquire an exclusive lock.
|
|
191
|
+
*
|
|
192
|
+
* Acquire an exclusive lock, and return a LockedPtr that can be used to
|
|
193
|
+
* safely access the datum.
|
|
194
|
+
*
|
|
195
|
+
* LockedPtr offers operator -> and * to provide access to the datum.
|
|
196
|
+
* The lock will be released when the LockedPtr is destroyed.
|
|
197
|
+
*
|
|
198
|
+
* @methodset Exclusive lock
|
|
199
|
+
*/
|
|
200
|
+
LockedPtr wlock() { return LockedPtr(static_cast<Subclass*>(this)); }
|
|
201
|
+
ConstWLockedPtr wlock() const {
|
|
202
|
+
return ConstWLockedPtr(static_cast<const Subclass*>(this));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @brief Acquire an exclusive lock, or null.
|
|
207
|
+
*
|
|
208
|
+
* Attempts to acquire the lock in exclusive mode. If acquisition is
|
|
209
|
+
* unsuccessful, the returned LockedPtr will be null.
|
|
210
|
+
*
|
|
211
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
212
|
+
* validity.)
|
|
213
|
+
*
|
|
214
|
+
* @methodset Exclusive lock
|
|
215
|
+
*/
|
|
216
|
+
TryWLockedPtr tryWLock() {
|
|
217
|
+
return TryWLockedPtr{static_cast<Subclass*>(this)};
|
|
218
|
+
}
|
|
219
|
+
ConstTryWLockedPtr tryWLock() const {
|
|
220
|
+
return ConstTryWLockedPtr{static_cast<const Subclass*>(this)};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @brief Acquire a read lock.
|
|
225
|
+
*
|
|
226
|
+
* The returned LockedPtr will force const access to the data unless the lock
|
|
227
|
+
* is acquired in non-const context and asNonConstUnsafe() is used.
|
|
228
|
+
*
|
|
229
|
+
* @methodset Shared lock
|
|
230
|
+
*/
|
|
231
|
+
RLockedPtr rlock() { return RLockedPtr(static_cast<Subclass*>(this)); }
|
|
232
|
+
ConstLockedPtr rlock() const {
|
|
233
|
+
return ConstLockedPtr(static_cast<const Subclass*>(this));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @brief Acquire a read lock, or null.
|
|
238
|
+
*
|
|
239
|
+
* Attempts to acquire the lock in shared mode. If acquisition is
|
|
240
|
+
* unsuccessful, the returned LockedPtr will be null.
|
|
241
|
+
*
|
|
242
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
243
|
+
* validity.)
|
|
244
|
+
*
|
|
245
|
+
* @methodset Shared lock
|
|
246
|
+
*/
|
|
247
|
+
TryRLockedPtr tryRLock() {
|
|
248
|
+
return TryRLockedPtr{static_cast<Subclass*>(this)};
|
|
249
|
+
}
|
|
250
|
+
ConstTryRLockedPtr tryRLock() const {
|
|
251
|
+
return ConstTryRLockedPtr{static_cast<const Subclass*>(this)};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Attempts to acquire the lock, or fails if the timeout elapses first.
|
|
256
|
+
* If acquisition is unsuccessful, the returned LockedPtr will be null.
|
|
257
|
+
*
|
|
258
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
259
|
+
* validity.)
|
|
260
|
+
*
|
|
261
|
+
* @methodset Exclusive lock
|
|
262
|
+
*/
|
|
263
|
+
template <class Rep, class Period>
|
|
264
|
+
LockedPtr wlock(const std::chrono::duration<Rep, Period>& timeout) {
|
|
265
|
+
return LockedPtr(static_cast<Subclass*>(this), timeout);
|
|
266
|
+
}
|
|
267
|
+
template <class Rep, class Period>
|
|
268
|
+
LockedPtr wlock(const std::chrono::duration<Rep, Period>& timeout) const {
|
|
269
|
+
return LockedPtr(static_cast<const Subclass*>(this), timeout);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Attempts to acquire the lock, or fails if the timeout elapses first.
|
|
274
|
+
* If acquisition is unsuccessful, the returned LockedPtr will be null.
|
|
275
|
+
*
|
|
276
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
277
|
+
* validity.)
|
|
278
|
+
*
|
|
279
|
+
* @methodset Shared lock
|
|
280
|
+
*/
|
|
281
|
+
template <class Rep, class Period>
|
|
282
|
+
RLockedPtr rlock(const std::chrono::duration<Rep, Period>& timeout) {
|
|
283
|
+
return RLockedPtr(static_cast<Subclass*>(this), timeout);
|
|
284
|
+
}
|
|
285
|
+
template <class Rep, class Period>
|
|
286
|
+
ConstRLockedPtr rlock(
|
|
287
|
+
const std::chrono::duration<Rep, Period>& timeout) const {
|
|
288
|
+
return ConstRLockedPtr(static_cast<const Subclass*>(this), timeout);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Invoke a function while holding the lock exclusively.
|
|
293
|
+
*
|
|
294
|
+
* A reference to the datum will be passed into the function as its only
|
|
295
|
+
* argument.
|
|
296
|
+
*
|
|
297
|
+
* This can be used with a lambda argument for easily defining small critical
|
|
298
|
+
* sections in the code. For example:
|
|
299
|
+
*
|
|
300
|
+
* auto value = obj.withWLock([](auto& data) {
|
|
301
|
+
* data.doStuff();
|
|
302
|
+
* return data.getValue();
|
|
303
|
+
* });
|
|
304
|
+
*
|
|
305
|
+
* @methodset Exclusive lock
|
|
306
|
+
*/
|
|
307
|
+
template <class Function>
|
|
308
|
+
auto withWLock(Function&& function) {
|
|
309
|
+
return function(*wlock());
|
|
310
|
+
}
|
|
311
|
+
template <class Function>
|
|
312
|
+
auto withWLock(Function&& function) const {
|
|
313
|
+
return function(*wlock());
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Invoke a function while holding the lock exclusively.
|
|
318
|
+
*
|
|
319
|
+
* This is similar to withWLock(), but the function will be passed a
|
|
320
|
+
* LockedPtr rather than a reference to the data itself.
|
|
321
|
+
*
|
|
322
|
+
* This allows scopedUnlock() to be called on the LockedPtr argument if
|
|
323
|
+
* desired.
|
|
324
|
+
*
|
|
325
|
+
* @methodset Exclusive lock
|
|
326
|
+
*/
|
|
327
|
+
template <class Function>
|
|
328
|
+
auto withWLockPtr(Function&& function) {
|
|
329
|
+
return function(wlock());
|
|
330
|
+
}
|
|
331
|
+
template <class Function>
|
|
332
|
+
auto withWLockPtr(Function&& function) const {
|
|
333
|
+
return function(wlock());
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Invoke a function while holding an the lock in shared mode.
|
|
338
|
+
*
|
|
339
|
+
* A const reference to the datum will be passed into the function as its
|
|
340
|
+
* only argument.
|
|
341
|
+
*
|
|
342
|
+
* @methodset Shared lock
|
|
343
|
+
*/
|
|
344
|
+
template <class Function>
|
|
345
|
+
auto withRLock(Function&& function) const {
|
|
346
|
+
return function(*rlock());
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Invoke a function while holding the lock in shared mode.
|
|
351
|
+
*
|
|
352
|
+
* This is similar to withRLock(), but the function will be passed a
|
|
353
|
+
* LockedPtr rather than a reference to the data itself.
|
|
354
|
+
*
|
|
355
|
+
* This allows scopedUnlock() to be called on the LockedPtr argument if
|
|
356
|
+
* desired.
|
|
357
|
+
*
|
|
358
|
+
* @methodset Shared lock
|
|
359
|
+
*/
|
|
360
|
+
template <class Function>
|
|
361
|
+
auto withRLockPtr(Function&& function) {
|
|
362
|
+
return function(rlock());
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
template <class Function>
|
|
366
|
+
auto withRLockPtr(Function&& function) const {
|
|
367
|
+
return function(rlock());
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* SynchronizedBase specialization for upgrade mutex types.
|
|
373
|
+
*
|
|
374
|
+
* This class provides all the functionality provided by the SynchronizedBase
|
|
375
|
+
* specialization for shared mutexes and a ulock() method that returns an
|
|
376
|
+
* upgrade lock RAII proxy
|
|
377
|
+
*/
|
|
378
|
+
template <class Subclass>
|
|
379
|
+
class SynchronizedBase<Subclass, detail::SynchronizedMutexLevel::Upgrade>
|
|
380
|
+
: public SynchronizedBase<
|
|
381
|
+
Subclass,
|
|
382
|
+
detail::SynchronizedMutexLevel::Shared> {
|
|
383
|
+
private:
|
|
384
|
+
template <typename T, typename P>
|
|
385
|
+
using LockedPtr_ = ::folly::LockedPtr<T, P>;
|
|
386
|
+
|
|
387
|
+
public:
|
|
388
|
+
using LockPolicyUpgrade = detail::SynchronizedLockPolicyUpgrade;
|
|
389
|
+
using LockPolicyTryUpgrade = detail::SynchronizedLockPolicyTryUpgrade;
|
|
390
|
+
|
|
391
|
+
using UpgradeLockedPtr = LockedPtr_<Subclass, LockPolicyUpgrade>;
|
|
392
|
+
using ConstUpgradeLockedPtr = LockedPtr_<const Subclass, LockPolicyUpgrade>;
|
|
393
|
+
|
|
394
|
+
using TryUpgradeLockedPtr = LockedPtr_<Subclass, LockPolicyTryUpgrade>;
|
|
395
|
+
using ConstTryUpgradeLockedPtr =
|
|
396
|
+
LockedPtr_<const Subclass, LockPolicyTryUpgrade>;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* @brief Acquire an upgrade lock.
|
|
400
|
+
*
|
|
401
|
+
* The returned LockedPtr will have force const access to the data unless the
|
|
402
|
+
* lock is acquired in non-const context and asNonConstUnsafe() is used.
|
|
403
|
+
*
|
|
404
|
+
* @methodset Upgrade lock
|
|
405
|
+
*/
|
|
406
|
+
UpgradeLockedPtr ulock() {
|
|
407
|
+
return UpgradeLockedPtr(static_cast<Subclass*>(this));
|
|
408
|
+
}
|
|
409
|
+
ConstUpgradeLockedPtr ulock() const {
|
|
410
|
+
return ConstUpgradeLockedPtr(static_cast<const Subclass*>(this));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @brief Acquire an upgrade lock, or null.
|
|
415
|
+
*
|
|
416
|
+
* Attempts to acquire the lock in upgrade mode. If acquisition is
|
|
417
|
+
* unsuccessful, the returned LockedPtr will be null.
|
|
418
|
+
*
|
|
419
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
420
|
+
* validity.)
|
|
421
|
+
*
|
|
422
|
+
* @methodset Upgrade lock
|
|
423
|
+
*/
|
|
424
|
+
TryUpgradeLockedPtr tryULock() {
|
|
425
|
+
return TryUpgradeLockedPtr{static_cast<Subclass*>(this)};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Acquire an upgrade lock and return a LockedPtr that can be used to safely
|
|
430
|
+
* access the datum
|
|
431
|
+
*
|
|
432
|
+
* And the const version
|
|
433
|
+
*
|
|
434
|
+
* @methodset Upgrade lock
|
|
435
|
+
*/
|
|
436
|
+
template <class Rep, class Period>
|
|
437
|
+
UpgradeLockedPtr ulock(const std::chrono::duration<Rep, Period>& timeout) {
|
|
438
|
+
return UpgradeLockedPtr(static_cast<Subclass*>(this), timeout);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Invoke a function while holding the lock.
|
|
443
|
+
*
|
|
444
|
+
* A reference to the datum will be passed into the function as its only
|
|
445
|
+
* argument.
|
|
446
|
+
*
|
|
447
|
+
* This can be used with a lambda argument for easily defining small critical
|
|
448
|
+
* sections in the code. For example:
|
|
449
|
+
*
|
|
450
|
+
* auto value = obj.withULock([](auto& data) {
|
|
451
|
+
* data.doStuff();
|
|
452
|
+
* return data.getValue();
|
|
453
|
+
* });
|
|
454
|
+
*
|
|
455
|
+
* This is probably not the function you want. If the intent is to read the
|
|
456
|
+
* data object and determine whether you should upgrade to a write lock then
|
|
457
|
+
* the withULockPtr() method should be called instead, since it gives access
|
|
458
|
+
* to the LockedPtr proxy (which can be upgraded via the
|
|
459
|
+
* moveFromUpgradeToWrite() method)
|
|
460
|
+
*
|
|
461
|
+
* @methodset Upgrade lock
|
|
462
|
+
*/
|
|
463
|
+
template <class Function>
|
|
464
|
+
auto withULock(Function&& function) {
|
|
465
|
+
return function(*ulock());
|
|
466
|
+
}
|
|
467
|
+
template <class Function>
|
|
468
|
+
auto withULock(Function&& function) const {
|
|
469
|
+
return function(*ulock());
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Invoke a function while holding the lock exclusively.
|
|
474
|
+
*
|
|
475
|
+
* This is similar to withULock(), but the function will be passed a
|
|
476
|
+
* LockedPtr rather than a reference to the data itself.
|
|
477
|
+
*
|
|
478
|
+
* This allows scopedUnlock() and as_lock() to be called on the
|
|
479
|
+
* LockedPtr argument.
|
|
480
|
+
*
|
|
481
|
+
* This also allows you to upgrade the LockedPtr proxy to a write state so
|
|
482
|
+
* that changes can be made to the underlying data
|
|
483
|
+
*
|
|
484
|
+
* @methodset Upgrade lock
|
|
485
|
+
*/
|
|
486
|
+
template <class Function>
|
|
487
|
+
auto withULockPtr(Function&& function) {
|
|
488
|
+
return function(ulock());
|
|
489
|
+
}
|
|
490
|
+
template <class Function>
|
|
491
|
+
auto withULockPtr(Function&& function) const {
|
|
492
|
+
return function(ulock());
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* SynchronizedBase specialization for non-shared mutex types.
|
|
498
|
+
*
|
|
499
|
+
* This class provides lock() methods for acquiring the lock and accessing the
|
|
500
|
+
* data.
|
|
501
|
+
*/
|
|
502
|
+
template <class Subclass>
|
|
503
|
+
class SynchronizedBase<Subclass, detail::SynchronizedMutexLevel::Unique> {
|
|
504
|
+
private:
|
|
505
|
+
template <typename T, typename P>
|
|
506
|
+
using LockedPtr_ = ::folly::LockedPtr<T, P>;
|
|
507
|
+
|
|
508
|
+
public:
|
|
509
|
+
using LockPolicyExclusive = detail::SynchronizedLockPolicyExclusive;
|
|
510
|
+
using LockPolicyTryExclusive = detail::SynchronizedLockPolicyTryExclusive;
|
|
511
|
+
|
|
512
|
+
using LockedPtr = LockedPtr_<Subclass, LockPolicyExclusive>;
|
|
513
|
+
using ConstLockedPtr = LockedPtr_<const Subclass, LockPolicyExclusive>;
|
|
514
|
+
|
|
515
|
+
using TryLockedPtr = LockedPtr_<Subclass, LockPolicyTryExclusive>;
|
|
516
|
+
using ConstTryLockedPtr = LockedPtr_<const Subclass, LockPolicyTryExclusive>;
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* @brief Acquire the lock.
|
|
520
|
+
*
|
|
521
|
+
* Return a LockedPtr that can be used to safely access the datum.
|
|
522
|
+
*
|
|
523
|
+
* @methodset Non-shareable lock
|
|
524
|
+
*/
|
|
525
|
+
LockedPtr lock() { return LockedPtr(static_cast<Subclass*>(this)); }
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Acquire a lock, and return a ConstLockedPtr that can be used to safely
|
|
529
|
+
* access the datum.
|
|
530
|
+
*
|
|
531
|
+
* @methodset Non-shareable lock
|
|
532
|
+
*/
|
|
533
|
+
ConstLockedPtr lock() const {
|
|
534
|
+
return ConstLockedPtr(static_cast<const Subclass*>(this));
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* @brief Acquire the lock, or null.
|
|
539
|
+
*
|
|
540
|
+
* Attempts to acquire the lock in exclusive mode. If acquisition is
|
|
541
|
+
* unsuccessful, the returned LockedPtr will be null.
|
|
542
|
+
*
|
|
543
|
+
* (Use LockedPtr::operator bool() or LockedPtr::isNull() to check for
|
|
544
|
+
* validity.)
|
|
545
|
+
*
|
|
546
|
+
* @methodset Non-shareable lock
|
|
547
|
+
*/
|
|
548
|
+
TryLockedPtr tryLock() { return TryLockedPtr{static_cast<Subclass*>(this)}; }
|
|
549
|
+
ConstTryLockedPtr tryLock() const {
|
|
550
|
+
return ConstTryLockedPtr{static_cast<const Subclass*>(this)};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Attempts to acquire the lock, or fails if the timeout elapses first.
|
|
555
|
+
* If acquisition is unsuccessful, the returned LockedPtr will be null.
|
|
556
|
+
*
|
|
557
|
+
* @methodset Non-shareable lock
|
|
558
|
+
*/
|
|
559
|
+
template <class Rep, class Period>
|
|
560
|
+
LockedPtr lock(const std::chrono::duration<Rep, Period>& timeout) {
|
|
561
|
+
return LockedPtr(static_cast<Subclass*>(this), timeout);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Attempts to acquire the lock, or fails if the timeout elapses first.
|
|
566
|
+
* If acquisition is unsuccessful, the returned LockedPtr will be null.
|
|
567
|
+
*
|
|
568
|
+
* @methodset Non-shareable lock
|
|
569
|
+
*/
|
|
570
|
+
template <class Rep, class Period>
|
|
571
|
+
ConstLockedPtr lock(const std::chrono::duration<Rep, Period>& timeout) const {
|
|
572
|
+
return ConstLockedPtr(static_cast<const Subclass*>(this), timeout);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Invoke a function while holding the lock.
|
|
577
|
+
*
|
|
578
|
+
* A reference to the datum will be passed into the function as its only
|
|
579
|
+
* argument.
|
|
580
|
+
*
|
|
581
|
+
* This can be used with a lambda argument for easily defining small critical
|
|
582
|
+
* sections in the code. For example:
|
|
583
|
+
*
|
|
584
|
+
* auto value = obj.withLock([](auto& data) {
|
|
585
|
+
* data.doStuff();
|
|
586
|
+
* return data.getValue();
|
|
587
|
+
* });
|
|
588
|
+
*
|
|
589
|
+
* @methodset Non-shareable lock
|
|
590
|
+
*/
|
|
591
|
+
template <class Function>
|
|
592
|
+
auto withLock(Function&& function) {
|
|
593
|
+
return function(*lock());
|
|
594
|
+
}
|
|
595
|
+
template <class Function>
|
|
596
|
+
auto withLock(Function&& function) const {
|
|
597
|
+
return function(*lock());
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Invoke a function while holding the lock exclusively.
|
|
602
|
+
*
|
|
603
|
+
* This is similar to withWLock(), but the function will be passed a
|
|
604
|
+
* LockedPtr rather than a reference to the data itself.
|
|
605
|
+
*
|
|
606
|
+
* This allows scopedUnlock() and as_lock() to be called on the
|
|
607
|
+
* LockedPtr argument.
|
|
608
|
+
*
|
|
609
|
+
* @methodset Non-shareable lock
|
|
610
|
+
*/
|
|
611
|
+
template <class Function>
|
|
612
|
+
auto withLockPtr(Function&& function) {
|
|
613
|
+
return function(lock());
|
|
614
|
+
}
|
|
615
|
+
template <class Function>
|
|
616
|
+
auto withLockPtr(Function&& function) const {
|
|
617
|
+
return function(lock());
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* `folly::Synchronized` pairs a datum with a mutex. The datum can only be
|
|
623
|
+
* reached through a `LockedPtr`, typically acquired via `.rlock()` or
|
|
624
|
+
* `.wlock()`; the mutex is held for the lifetime of the `LockedPtr`.
|
|
625
|
+
*
|
|
626
|
+
* It is recommended to explicitly open a new nested scope when aquiring
|
|
627
|
+
* a `LockedPtr` object, to help visibly delineate the critical section and to
|
|
628
|
+
* ensure that the `LockedPtr` is destroyed as soon as it is no longer needed.
|
|
629
|
+
*
|
|
630
|
+
* @tparam T The type of datum to be stored.
|
|
631
|
+
* @tparam Mutex The mutex type that guards the datum. Must be Lockable.
|
|
632
|
+
*
|
|
633
|
+
* @refcode folly/docs/examples/folly/Synchronized.cpp
|
|
634
|
+
*/
|
|
635
|
+
template <class T, class Mutex = SharedMutex>
|
|
636
|
+
struct Synchronized : public SynchronizedBase<
|
|
637
|
+
Synchronized<T, Mutex>,
|
|
638
|
+
detail::kSynchronizedMutexLevel<Mutex>> {
|
|
639
|
+
private:
|
|
640
|
+
using Base = SynchronizedBase<
|
|
641
|
+
Synchronized<T, Mutex>,
|
|
642
|
+
detail::kSynchronizedMutexLevel<Mutex>>;
|
|
643
|
+
static constexpr bool nxCopyCtor{
|
|
644
|
+
std::is_nothrow_copy_constructible<T>::value};
|
|
645
|
+
static constexpr bool nxMoveCtor{
|
|
646
|
+
std::is_nothrow_move_constructible<T>::value};
|
|
647
|
+
|
|
648
|
+
// used to disable copy construction and assignment
|
|
649
|
+
class NonImplementedType;
|
|
650
|
+
|
|
651
|
+
public:
|
|
652
|
+
using LockedPtr = typename Base::LockedPtr;
|
|
653
|
+
using ConstLockedPtr = typename Base::ConstLockedPtr;
|
|
654
|
+
using DataType = T;
|
|
655
|
+
using MutexType = Mutex;
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Default constructor leaves both members call their own default constructor.
|
|
659
|
+
*/
|
|
660
|
+
constexpr Synchronized() = default;
|
|
661
|
+
|
|
662
|
+
public:
|
|
663
|
+
/**
|
|
664
|
+
* Copy constructor. Enabled only when the data type is copy-constructible.
|
|
665
|
+
*
|
|
666
|
+
* Takes a shared-or-exclusive lock on the source mutex while performing the
|
|
667
|
+
* copy-construction of the destination data from the source data. No lock is
|
|
668
|
+
* taken on the destination mutex.
|
|
669
|
+
*
|
|
670
|
+
* May throw even when the data type is is nothrow-copy-constructible because
|
|
671
|
+
* acquiring a lock may throw.
|
|
672
|
+
*
|
|
673
|
+
* deprecated
|
|
674
|
+
*/
|
|
675
|
+
/* implicit */ Synchronized(typename std::conditional<
|
|
676
|
+
std::is_copy_constructible<T>::value,
|
|
677
|
+
const Synchronized&,
|
|
678
|
+
NonImplementedType>::type rhs) /* may throw */
|
|
679
|
+
: Synchronized(rhs.copy()) {}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Move-constructs from the source data without locking either the source or
|
|
683
|
+
* the destination mutex.
|
|
684
|
+
*
|
|
685
|
+
* Semantically, assumes that the source object is a true rvalue and therefore
|
|
686
|
+
* that no synchronization is required for accessing it.
|
|
687
|
+
*
|
|
688
|
+
* deprecated
|
|
689
|
+
*/
|
|
690
|
+
Synchronized(Synchronized&& rhs) noexcept(nxMoveCtor)
|
|
691
|
+
: Synchronized(std::move(rhs.datum_)) {}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Constructor taking a datum as argument copies it. There is no
|
|
695
|
+
* need to lock the constructing object.
|
|
696
|
+
*/
|
|
697
|
+
explicit Synchronized(const T& rhs) noexcept(nxCopyCtor) : datum_(rhs) {}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Constructor taking a datum rvalue as argument moves it. There is no need
|
|
701
|
+
* to lock the constructing object.
|
|
702
|
+
*/
|
|
703
|
+
explicit Synchronized(T&& rhs) noexcept(nxMoveCtor)
|
|
704
|
+
: datum_(std::move(rhs)) {}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Lets you construct non-movable types in-place. Use the constexpr
|
|
708
|
+
* instance `in_place` as the first argument.
|
|
709
|
+
*/
|
|
710
|
+
template <typename... Args>
|
|
711
|
+
explicit constexpr Synchronized(std::in_place_t, Args&&... args)
|
|
712
|
+
: datum_(std::forward<Args>(args)...) {}
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Lets you construct the synchronized object and also pass construction
|
|
716
|
+
* parameters to the underlying mutex if desired
|
|
717
|
+
*/
|
|
718
|
+
template <typename... DatumArgs, typename... MutexArgs>
|
|
719
|
+
Synchronized(
|
|
720
|
+
std::piecewise_construct_t,
|
|
721
|
+
std::tuple<DatumArgs...> datumArgs,
|
|
722
|
+
std::tuple<MutexArgs...> mutexArgs)
|
|
723
|
+
: Synchronized{
|
|
724
|
+
std::piecewise_construct,
|
|
725
|
+
std::move(datumArgs),
|
|
726
|
+
std::move(mutexArgs),
|
|
727
|
+
std::make_index_sequence<sizeof...(DatumArgs)>{},
|
|
728
|
+
std::make_index_sequence<sizeof...(MutexArgs)>{}} {}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Copy assignment operator.
|
|
732
|
+
*
|
|
733
|
+
* Enabled only when the data type is copy-constructible and move-assignable.
|
|
734
|
+
*
|
|
735
|
+
* Move-assigns from a copy of the source data.
|
|
736
|
+
*
|
|
737
|
+
* Takes a shared-or-exclusive lock on the source mutex while copying the
|
|
738
|
+
* source data to a temporary. Takes an exclusive lock on the destination
|
|
739
|
+
* mutex while move-assigning from the temporary.
|
|
740
|
+
*
|
|
741
|
+
* This technique consts an extra temporary but avoids the need to take locks
|
|
742
|
+
* on both mutexes together.
|
|
743
|
+
*
|
|
744
|
+
* deprecated
|
|
745
|
+
*/
|
|
746
|
+
Synchronized& operator=(typename std::conditional<
|
|
747
|
+
std::is_copy_constructible<T>::value &&
|
|
748
|
+
std::is_move_assignable<T>::value,
|
|
749
|
+
const Synchronized&,
|
|
750
|
+
NonImplementedType>::type rhs) {
|
|
751
|
+
return *this = rhs.copy();
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Move assignment operator.
|
|
756
|
+
*
|
|
757
|
+
* Takes an exclusive lock on the destination mutex while move-assigning the
|
|
758
|
+
* destination data from the source data. The source mutex is not locked or
|
|
759
|
+
* otherwise accessed.
|
|
760
|
+
*
|
|
761
|
+
* Semantically, assumes that the source object is a true rvalue and therefore
|
|
762
|
+
* that no synchronization is required for accessing it.
|
|
763
|
+
*
|
|
764
|
+
* deprecated
|
|
765
|
+
*/
|
|
766
|
+
Synchronized& operator=(Synchronized&& rhs) {
|
|
767
|
+
return *this = std::move(rhs.datum_);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Lock object, assign datum.
|
|
772
|
+
*/
|
|
773
|
+
Synchronized& operator=(const T& rhs) {
|
|
774
|
+
if (&datum_ != &rhs) {
|
|
775
|
+
auto guard = LockedPtr{this};
|
|
776
|
+
datum_ = rhs;
|
|
777
|
+
}
|
|
778
|
+
return *this;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* Lock object, move-assign datum.
|
|
783
|
+
*/
|
|
784
|
+
Synchronized& operator=(T&& rhs) {
|
|
785
|
+
if (&datum_ != &rhs) {
|
|
786
|
+
auto guard = LockedPtr{this};
|
|
787
|
+
datum_ = std::move(rhs);
|
|
788
|
+
}
|
|
789
|
+
return *this;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* @brief Acquire some lock.
|
|
794
|
+
*
|
|
795
|
+
* If the mutex is a shared mutex, and the Synchronized instance is const,
|
|
796
|
+
* this acquires a shared lock. Otherwise this acquires an exclusive lock.
|
|
797
|
+
*
|
|
798
|
+
* In general, prefer using the explicit rlock() and wlock() methods
|
|
799
|
+
* for read-write locks, and lock() for purely exclusive locks.
|
|
800
|
+
*
|
|
801
|
+
* contextualLock() is primarily intended for use in other template functions
|
|
802
|
+
* that do not necessarily know the lock type.
|
|
803
|
+
*/
|
|
804
|
+
LockedPtr contextualLock() { return LockedPtr(this); }
|
|
805
|
+
ConstLockedPtr contextualLock() const { return ConstLockedPtr(this); }
|
|
806
|
+
template <class Rep, class Period>
|
|
807
|
+
LockedPtr contextualLock(const std::chrono::duration<Rep, Period>& timeout) {
|
|
808
|
+
return LockedPtr(this, timeout);
|
|
809
|
+
}
|
|
810
|
+
template <class Rep, class Period>
|
|
811
|
+
ConstLockedPtr contextualLock(
|
|
812
|
+
const std::chrono::duration<Rep, Period>& timeout) const {
|
|
813
|
+
return ConstLockedPtr(this, timeout);
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* @brief Acquire a lock for reading.
|
|
817
|
+
*
|
|
818
|
+
* contextualRLock() acquires a read lock if the mutex type is shared,
|
|
819
|
+
* or a regular exclusive lock for non-shared mutex types.
|
|
820
|
+
*
|
|
821
|
+
* contextualRLock() when you know that you prefer a read lock (if
|
|
822
|
+
* available), even if the Synchronized<T> object itself is non-const.
|
|
823
|
+
*/
|
|
824
|
+
ConstLockedPtr contextualRLock() const { return ConstLockedPtr(this); }
|
|
825
|
+
template <class Rep, class Period>
|
|
826
|
+
ConstLockedPtr contextualRLock(
|
|
827
|
+
const std::chrono::duration<Rep, Period>& timeout) const {
|
|
828
|
+
return ConstLockedPtr(this, timeout);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* @brief Access the datum under lock.
|
|
833
|
+
*
|
|
834
|
+
* deprecated
|
|
835
|
+
*
|
|
836
|
+
* This accessor offers a LockedPtr. In turn, LockedPtr offers
|
|
837
|
+
* operator-> returning a pointer to T. The operator-> keeps
|
|
838
|
+
* expanding until it reaches a pointer, so syncobj->foo() will lock
|
|
839
|
+
* the object and call foo() against it.
|
|
840
|
+
*
|
|
841
|
+
* NOTE: This API is planned to be deprecated in an upcoming diff.
|
|
842
|
+
* Prefer using lock(), wlock(), or rlock() instead.
|
|
843
|
+
*/
|
|
844
|
+
[[deprecated("use explicit lock(), wlock(), or rlock() instead")]] LockedPtr
|
|
845
|
+
operator->() {
|
|
846
|
+
return LockedPtr(this);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* deprecated
|
|
851
|
+
*
|
|
852
|
+
* Obtain a ConstLockedPtr.
|
|
853
|
+
*
|
|
854
|
+
* NOTE: This API is planned to be deprecated in an upcoming diff.
|
|
855
|
+
* Prefer using lock(), wlock(), or rlock() instead.
|
|
856
|
+
*/
|
|
857
|
+
[[deprecated(
|
|
858
|
+
"use explicit lock(), wlock(), or rlock() instead")]] ConstLockedPtr
|
|
859
|
+
operator->() const {
|
|
860
|
+
return ConstLockedPtr(this);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* @brief Acquire a LockedPtr with timeout.
|
|
865
|
+
*
|
|
866
|
+
* Attempts to acquire for a given number of milliseconds. If
|
|
867
|
+
* acquisition is unsuccessful, the returned LockedPtr is nullptr.
|
|
868
|
+
*
|
|
869
|
+
* NOTE: This API is deprecated. Use lock(), wlock(), or rlock() instead.
|
|
870
|
+
* In the future it will be marked with a deprecation attribute to emit
|
|
871
|
+
* build-time warnings, and then it will be removed entirely.
|
|
872
|
+
*/
|
|
873
|
+
LockedPtr timedAcquire(unsigned int milliseconds) {
|
|
874
|
+
return LockedPtr(this, std::chrono::milliseconds(milliseconds));
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Attempts to acquire for a given number of milliseconds. If
|
|
879
|
+
* acquisition is unsuccessful, the returned ConstLockedPtr is nullptr.
|
|
880
|
+
*
|
|
881
|
+
* NOTE: This API is deprecated. Use lock(), wlock(), or rlock() instead.
|
|
882
|
+
* In the future it will be marked with a deprecation attribute to emit
|
|
883
|
+
* build-time warnings, and then it will be removed entirely.
|
|
884
|
+
*/
|
|
885
|
+
ConstLockedPtr timedAcquire(unsigned int milliseconds) const {
|
|
886
|
+
return ConstLockedPtr(this, std::chrono::milliseconds(milliseconds));
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* @brief Swap datum.
|
|
891
|
+
*
|
|
892
|
+
* Swaps with another Synchronized. Protected against
|
|
893
|
+
* self-swap. Only data is swapped. Locks are acquired in increasing
|
|
894
|
+
* address order.
|
|
895
|
+
*/
|
|
896
|
+
void swap(Synchronized& rhs) {
|
|
897
|
+
if (this == &rhs) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
if (this > &rhs) {
|
|
901
|
+
return rhs.swap(*this);
|
|
902
|
+
}
|
|
903
|
+
auto guard1 = LockedPtr{this};
|
|
904
|
+
auto guard2 = LockedPtr{&rhs};
|
|
905
|
+
|
|
906
|
+
using std::swap;
|
|
907
|
+
swap(datum_, rhs.datum_);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Swap with another datum. Recommended because it keeps the mutex
|
|
912
|
+
* held only briefly.
|
|
913
|
+
*/
|
|
914
|
+
void swap(T& rhs) {
|
|
915
|
+
LockedPtr guard(this);
|
|
916
|
+
|
|
917
|
+
using std::swap;
|
|
918
|
+
swap(datum_, rhs);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* @brief Exchange datum.
|
|
923
|
+
*
|
|
924
|
+
* Assign another datum and return the original value. Recommended
|
|
925
|
+
* because it keeps the mutex held only briefly.
|
|
926
|
+
*/
|
|
927
|
+
T exchange(T&& rhs) {
|
|
928
|
+
swap(rhs);
|
|
929
|
+
return std::move(rhs);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Copies datum to a given target.
|
|
934
|
+
*/
|
|
935
|
+
void copyInto(T& target) const {
|
|
936
|
+
ConstLockedPtr guard(this);
|
|
937
|
+
target = datum_;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Returns a fresh copy of the datum.
|
|
942
|
+
*/
|
|
943
|
+
T copy() const {
|
|
944
|
+
ConstLockedPtr guard(this);
|
|
945
|
+
return datum_;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* @brief Access datum without locking.
|
|
950
|
+
*
|
|
951
|
+
* Returns a reference to the datum without acquiring a lock.
|
|
952
|
+
*
|
|
953
|
+
* Provided as a backdoor for call-sites where it is known safe to be used.
|
|
954
|
+
* For example, when it is known that only one thread has access to the
|
|
955
|
+
* Synchronized instance.
|
|
956
|
+
*
|
|
957
|
+
* To be used with care - this method explicitly overrides the normal safety
|
|
958
|
+
* guarantees provided by the rest of the Synchronized API.
|
|
959
|
+
*/
|
|
960
|
+
T& unsafeGetUnlocked() { return datum_; }
|
|
961
|
+
const T& unsafeGetUnlocked() const { return datum_; }
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* @brief Access underlying mutex_ directly.
|
|
965
|
+
*
|
|
966
|
+
* Provided as a backdoor for call-sites where the lock and unlock are paired
|
|
967
|
+
* in different calls. For example, in fork handlers. Use carefully as the
|
|
968
|
+
* caller is responsible to ensure it is paired with an unlock and there is
|
|
969
|
+
* nothing else in between that tries to implicitly or explicitly acquire the
|
|
970
|
+
* lock again.
|
|
971
|
+
*/
|
|
972
|
+
Mutex& unsafeGetMutex() { return mutex_; }
|
|
973
|
+
|
|
974
|
+
private:
|
|
975
|
+
template <class LockedType, class MutexType, class LockPolicy>
|
|
976
|
+
friend class folly::LockedPtrBase;
|
|
977
|
+
template <class LockedType, class LockPolicy>
|
|
978
|
+
friend class folly::LockedPtr;
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Helper constructors to enable Synchronized for
|
|
982
|
+
* non-default constructible types T.
|
|
983
|
+
* Guards are created in actual public constructors and are alive
|
|
984
|
+
* for the time required to construct the object
|
|
985
|
+
*/
|
|
986
|
+
Synchronized(
|
|
987
|
+
const Synchronized& rhs,
|
|
988
|
+
const ConstLockedPtr& /*guard*/) noexcept(nxCopyCtor)
|
|
989
|
+
: datum_(rhs.datum_) {}
|
|
990
|
+
|
|
991
|
+
Synchronized(Synchronized&& rhs, const LockedPtr& /*guard*/) noexcept(
|
|
992
|
+
nxMoveCtor)
|
|
993
|
+
: datum_(std::move(rhs.datum_)) {}
|
|
994
|
+
|
|
995
|
+
template <
|
|
996
|
+
typename... DatumArgs,
|
|
997
|
+
typename... MutexArgs,
|
|
998
|
+
std::size_t... IndicesOne,
|
|
999
|
+
std::size_t... IndicesTwo>
|
|
1000
|
+
Synchronized(
|
|
1001
|
+
std::piecewise_construct_t,
|
|
1002
|
+
std::tuple<DatumArgs...> datumArgs,
|
|
1003
|
+
std::tuple<MutexArgs...> mutexArgs,
|
|
1004
|
+
std::index_sequence<IndicesOne...>,
|
|
1005
|
+
std::index_sequence<IndicesTwo...>)
|
|
1006
|
+
: datum_{std::get<IndicesOne>(std::move(datumArgs))...},
|
|
1007
|
+
mutex_{std::get<IndicesTwo>(std::move(mutexArgs))...} {}
|
|
1008
|
+
|
|
1009
|
+
// simulacrum of data members - keep data members in sync!
|
|
1010
|
+
// LockedPtr needs offsetof() which is specified only for standard-layout
|
|
1011
|
+
// types which Synchronized is not so we define a simulacrum for offsetof
|
|
1012
|
+
struct Simulacrum {
|
|
1013
|
+
aligned_storage_for_t<DataType> datum_;
|
|
1014
|
+
aligned_storage_for_t<MutexType> mutex_;
|
|
1015
|
+
};
|
|
1016
|
+
|
|
1017
|
+
// data members - keep simulacrum of data members in sync!
|
|
1018
|
+
T datum_;
|
|
1019
|
+
mutable Mutex mutex_;
|
|
1020
|
+
};
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Deprecated subclass of Synchronized that provides implicit locking
|
|
1024
|
+
* via operator->. This is intended to ease migration while preventing
|
|
1025
|
+
* accidental use of operator-> in new code.
|
|
1026
|
+
*/
|
|
1027
|
+
template <class T, class Mutex = SharedMutex>
|
|
1028
|
+
struct [[deprecated(
|
|
1029
|
+
"use Synchronized and explicit lock(), wlock(), or rlock() instead")]] ImplicitSynchronized
|
|
1030
|
+
: Synchronized<T, Mutex> {
|
|
1031
|
+
private:
|
|
1032
|
+
using Base = Synchronized<T, Mutex>;
|
|
1033
|
+
|
|
1034
|
+
public:
|
|
1035
|
+
using LockedPtr = typename Base::LockedPtr;
|
|
1036
|
+
using ConstLockedPtr = typename Base::ConstLockedPtr;
|
|
1037
|
+
using DataType = typename Base::DataType;
|
|
1038
|
+
using MutexType = typename Base::MutexType;
|
|
1039
|
+
|
|
1040
|
+
using Base::Base;
|
|
1041
|
+
using Base::operator=;
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
template <class SynchronizedType, class LockPolicy>
|
|
1045
|
+
class ScopedUnlocker;
|
|
1046
|
+
|
|
1047
|
+
namespace detail {
|
|
1048
|
+
/*
|
|
1049
|
+
* A helper alias that resolves to "const T" if the template parameter
|
|
1050
|
+
* is a const Synchronized<T>, or "T" if the parameter is not const.
|
|
1051
|
+
*/
|
|
1052
|
+
template <class SynchronizedType, bool AllowsConcurrentAccess>
|
|
1053
|
+
using SynchronizedDataType = typename std::conditional<
|
|
1054
|
+
AllowsConcurrentAccess || std::is_const<SynchronizedType>::value,
|
|
1055
|
+
typename SynchronizedType::DataType const,
|
|
1056
|
+
typename SynchronizedType::DataType>::type;
|
|
1057
|
+
/*
|
|
1058
|
+
* A helper alias that resolves to a ConstLockedPtr if the template parameter
|
|
1059
|
+
* is a const Synchronized<T>, or a LockedPtr if the parameter is not const.
|
|
1060
|
+
*/
|
|
1061
|
+
template <class SynchronizedType>
|
|
1062
|
+
using LockedPtrType = typename std::conditional<
|
|
1063
|
+
std::is_const<SynchronizedType>::value,
|
|
1064
|
+
typename SynchronizedType::ConstLockedPtr,
|
|
1065
|
+
typename SynchronizedType::LockedPtr>::type;
|
|
1066
|
+
|
|
1067
|
+
template <
|
|
1068
|
+
typename Synchronized,
|
|
1069
|
+
typename LockFunc,
|
|
1070
|
+
typename TryLockFunc,
|
|
1071
|
+
typename... Args>
|
|
1072
|
+
class SynchronizedLocker {
|
|
1073
|
+
public:
|
|
1074
|
+
using LockedPtr = invoke_result_t<LockFunc&, Synchronized&, const Args&...>;
|
|
1075
|
+
|
|
1076
|
+
template <typename LockFuncType, typename TryLockFuncType, typename... As>
|
|
1077
|
+
SynchronizedLocker(
|
|
1078
|
+
Synchronized& sync,
|
|
1079
|
+
LockFuncType&& lockFunc,
|
|
1080
|
+
TryLockFuncType tryLockFunc,
|
|
1081
|
+
As&&... as)
|
|
1082
|
+
: synchronized{sync},
|
|
1083
|
+
lockFunc_{std::forward<LockFuncType>(lockFunc)},
|
|
1084
|
+
tryLockFunc_{std::forward<TryLockFuncType>(tryLockFunc)},
|
|
1085
|
+
args_{std::forward<As>(as)...} {}
|
|
1086
|
+
|
|
1087
|
+
auto lock() const {
|
|
1088
|
+
auto args = std::tuple<const Args&...>{args_};
|
|
1089
|
+
return apply(lockFunc_, std::tuple_cat(std::tie(synchronized), args));
|
|
1090
|
+
}
|
|
1091
|
+
auto tryLock() const { return tryLockFunc_(synchronized); }
|
|
1092
|
+
|
|
1093
|
+
private:
|
|
1094
|
+
Synchronized& synchronized;
|
|
1095
|
+
LockFunc lockFunc_;
|
|
1096
|
+
TryLockFunc tryLockFunc_;
|
|
1097
|
+
std::tuple<Args...> args_;
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1100
|
+
template <
|
|
1101
|
+
typename Synchronized,
|
|
1102
|
+
typename LockFunc,
|
|
1103
|
+
typename TryLockFunc,
|
|
1104
|
+
typename... Args>
|
|
1105
|
+
auto makeSynchronizedLocker(
|
|
1106
|
+
Synchronized& synchronized,
|
|
1107
|
+
LockFunc&& lockFunc,
|
|
1108
|
+
TryLockFunc&& tryLockFunc,
|
|
1109
|
+
Args&&... args) {
|
|
1110
|
+
using LockFuncType = std::decay_t<LockFunc>;
|
|
1111
|
+
using TryLockFuncType = std::decay_t<TryLockFunc>;
|
|
1112
|
+
return SynchronizedLocker<
|
|
1113
|
+
Synchronized,
|
|
1114
|
+
LockFuncType,
|
|
1115
|
+
TryLockFuncType,
|
|
1116
|
+
std::decay_t<Args>...>{
|
|
1117
|
+
synchronized,
|
|
1118
|
+
std::forward<LockFunc>(lockFunc),
|
|
1119
|
+
std::forward<TryLockFunc>(tryLockFunc),
|
|
1120
|
+
std::forward<Args>(args)...};
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* Acquire locks for multiple Synchronized<T> objects, in a deadlock-safe
|
|
1125
|
+
* manner.
|
|
1126
|
+
*
|
|
1127
|
+
* The function uses the "smart and polite" algorithm from this link
|
|
1128
|
+
* http://howardhinnant.github.io/dining_philosophers.html#Polite
|
|
1129
|
+
*
|
|
1130
|
+
* The gist of the algorithm is that it locks a mutex, then tries to lock the
|
|
1131
|
+
* other mutexes in a non-blocking manner. If all the locks succeed, we are
|
|
1132
|
+
* done, if not, we release the locks we have held, yield to allow other
|
|
1133
|
+
* threads to continue and then block on the mutex that we failed to acquire.
|
|
1134
|
+
*
|
|
1135
|
+
* This allows dynamically yielding ownership of all the mutexes but one, so
|
|
1136
|
+
* that other threads can continue doing work and locking the other mutexes.
|
|
1137
|
+
* See the benchmarks in folly/test/SynchronizedBenchmark.cpp for more.
|
|
1138
|
+
*/
|
|
1139
|
+
template <typename... SynchronizedLocker>
|
|
1140
|
+
auto lock(SynchronizedLocker... lockersIn)
|
|
1141
|
+
-> std::tuple<typename SynchronizedLocker::LockedPtr...> {
|
|
1142
|
+
// capture the list of lockers as a tuple
|
|
1143
|
+
auto lockers = std::forward_as_tuple(lockersIn...);
|
|
1144
|
+
|
|
1145
|
+
// make a list of null LockedPtr instances that we will return to the caller
|
|
1146
|
+
auto lockedPtrs = std::tuple<typename SynchronizedLocker::LockedPtr...>{};
|
|
1147
|
+
|
|
1148
|
+
// start by locking the first thing in the list
|
|
1149
|
+
std::get<0>(lockedPtrs) = std::get<0>(lockers).lock();
|
|
1150
|
+
auto indexLocked = 0;
|
|
1151
|
+
|
|
1152
|
+
while (true) {
|
|
1153
|
+
auto couldLockAll = true;
|
|
1154
|
+
|
|
1155
|
+
for_each(lockers, [&](auto& locker, auto index) {
|
|
1156
|
+
// if we should try_lock on the current locker then do so
|
|
1157
|
+
if (index != indexLocked) {
|
|
1158
|
+
auto lockedPtr = locker.tryLock();
|
|
1159
|
+
|
|
1160
|
+
// if we were unable to lock this mutex,
|
|
1161
|
+
//
|
|
1162
|
+
// 1. release all the locks,
|
|
1163
|
+
// 2. yield control to another thread to be nice
|
|
1164
|
+
// 3. block on the mutex we failed to lock, acquire the lock
|
|
1165
|
+
// 4. break out and set the index of the current mutex to indicate
|
|
1166
|
+
// which mutex we have locked
|
|
1167
|
+
if (!lockedPtr) {
|
|
1168
|
+
// writing lockedPtrs = decltype(lockedPtrs){} does not compile on
|
|
1169
|
+
// gcc, I believe this is a bug D7676798
|
|
1170
|
+
lockedPtrs = std::tuple<typename SynchronizedLocker::LockedPtr...>{};
|
|
1171
|
+
|
|
1172
|
+
std::this_thread::yield();
|
|
1173
|
+
fetch(lockedPtrs, index) = locker.lock();
|
|
1174
|
+
indexLocked = index;
|
|
1175
|
+
couldLockAll = false;
|
|
1176
|
+
|
|
1177
|
+
return loop_break;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// else store the locked mutex in the list we return
|
|
1181
|
+
fetch(lockedPtrs, index) = std::move(lockedPtr);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
return loop_continue;
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
if (couldLockAll) {
|
|
1188
|
+
return lockedPtrs;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
template <typename Synchronized, typename... Args>
|
|
1194
|
+
auto wlock(Synchronized& synchronized, Args&&... args) {
|
|
1195
|
+
return detail::makeSynchronizedLocker(
|
|
1196
|
+
synchronized,
|
|
1197
|
+
[](auto& s, auto&&... a) {
|
|
1198
|
+
return s.wlock(std::forward<decltype(a)>(a)...);
|
|
1199
|
+
},
|
|
1200
|
+
[](auto& s) { return s.tryWLock(); },
|
|
1201
|
+
std::forward<Args>(args)...);
|
|
1202
|
+
}
|
|
1203
|
+
template <typename Synchronized, typename... Args>
|
|
1204
|
+
auto rlock(Synchronized& synchronized, Args&&... args) {
|
|
1205
|
+
return detail::makeSynchronizedLocker(
|
|
1206
|
+
synchronized,
|
|
1207
|
+
[](auto& s, auto&&... a) {
|
|
1208
|
+
return s.rlock(std::forward<decltype(a)>(a)...);
|
|
1209
|
+
},
|
|
1210
|
+
[](auto& s) { return s.tryRLock(); },
|
|
1211
|
+
std::forward<Args>(args)...);
|
|
1212
|
+
}
|
|
1213
|
+
template <typename Synchronized, typename... Args>
|
|
1214
|
+
auto ulock(Synchronized& synchronized, Args&&... args) {
|
|
1215
|
+
return detail::makeSynchronizedLocker(
|
|
1216
|
+
synchronized,
|
|
1217
|
+
[](auto& s, auto&&... a) {
|
|
1218
|
+
return s.ulock(std::forward<decltype(a)>(a)...);
|
|
1219
|
+
},
|
|
1220
|
+
[](auto& s) { return s.tryULock(); },
|
|
1221
|
+
std::forward<Args>(args)...);
|
|
1222
|
+
}
|
|
1223
|
+
template <typename Synchronized, typename... Args>
|
|
1224
|
+
auto lock(Synchronized& synchronized, Args&&... args) {
|
|
1225
|
+
return detail::makeSynchronizedLocker(
|
|
1226
|
+
synchronized,
|
|
1227
|
+
[](auto& s, auto&&... a) {
|
|
1228
|
+
return s.lock(std::forward<decltype(a)>(a)...);
|
|
1229
|
+
},
|
|
1230
|
+
[](auto& s) { return s.tryLock(); },
|
|
1231
|
+
std::forward<Args>(args)...);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
} // namespace detail
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* This class temporarily unlocks a LockedPtr in a scoped manner.
|
|
1238
|
+
*/
|
|
1239
|
+
template <class SynchronizedType, class LockPolicy>
|
|
1240
|
+
class ScopedUnlocker {
|
|
1241
|
+
public:
|
|
1242
|
+
explicit ScopedUnlocker(LockedPtr<SynchronizedType, LockPolicy>* p) noexcept
|
|
1243
|
+
: ptr_(p), parent_(p->parent()) {
|
|
1244
|
+
ptr_->releaseLock();
|
|
1245
|
+
}
|
|
1246
|
+
ScopedUnlocker(const ScopedUnlocker&) = delete;
|
|
1247
|
+
ScopedUnlocker& operator=(const ScopedUnlocker&) = delete;
|
|
1248
|
+
ScopedUnlocker(ScopedUnlocker&& other) noexcept
|
|
1249
|
+
: ptr_(std::exchange(other.ptr_, nullptr)),
|
|
1250
|
+
parent_(std::exchange(other.parent_, nullptr)) {}
|
|
1251
|
+
ScopedUnlocker& operator=(ScopedUnlocker&& other) = delete;
|
|
1252
|
+
|
|
1253
|
+
~ScopedUnlocker() noexcept(false) {
|
|
1254
|
+
if (ptr_) {
|
|
1255
|
+
ptr_->reacquireLock(parent_);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
private:
|
|
1260
|
+
LockedPtr<SynchronizedType, LockPolicy>* ptr_{nullptr};
|
|
1261
|
+
SynchronizedType* parent_{nullptr};
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
/**
|
|
1265
|
+
* A LockedPtr keeps a Synchronized<T> object locked for the duration of
|
|
1266
|
+
* LockedPtr's existence.
|
|
1267
|
+
*
|
|
1268
|
+
* It provides access the datum's members directly by using operator->() and
|
|
1269
|
+
* operator*().
|
|
1270
|
+
*
|
|
1271
|
+
* The LockPolicy parameter controls whether or not the lock is acquired in
|
|
1272
|
+
* exclusive or shared mode.
|
|
1273
|
+
*/
|
|
1274
|
+
template <class SynchronizedType, class LockPolicy>
|
|
1275
|
+
class LockedPtr {
|
|
1276
|
+
private:
|
|
1277
|
+
constexpr static bool AllowsConcurrentAccess =
|
|
1278
|
+
LockPolicy::level != detail::SynchronizedMutexLevel::Unique;
|
|
1279
|
+
|
|
1280
|
+
using CDataType = // the DataType with the appropriate const-qualification
|
|
1281
|
+
detail::SynchronizedDataType<SynchronizedType, AllowsConcurrentAccess>;
|
|
1282
|
+
|
|
1283
|
+
template <typename LockPolicyOther>
|
|
1284
|
+
using EnableIfSameLevel =
|
|
1285
|
+
std::enable_if_t<LockPolicy::level == LockPolicyOther::level>;
|
|
1286
|
+
|
|
1287
|
+
template <typename, typename>
|
|
1288
|
+
friend class LockedPtr;
|
|
1289
|
+
|
|
1290
|
+
friend class ScopedUnlocker<SynchronizedType, LockPolicy>;
|
|
1291
|
+
|
|
1292
|
+
public:
|
|
1293
|
+
using DataType = typename SynchronizedType::DataType;
|
|
1294
|
+
using MutexType = typename SynchronizedType::MutexType;
|
|
1295
|
+
using Synchronized = typename std::remove_const<SynchronizedType>::type;
|
|
1296
|
+
using LockType = detail::SynchronizedLockType<LockPolicy::level, MutexType>;
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* Creates an uninitialized LockedPtr.
|
|
1300
|
+
*
|
|
1301
|
+
* Dereferencing an uninitialized LockedPtr is not allowed.
|
|
1302
|
+
*/
|
|
1303
|
+
LockedPtr() = default;
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* Takes a Synchronized<T> and locks it.
|
|
1307
|
+
*/
|
|
1308
|
+
explicit LockedPtr(SynchronizedType* parent)
|
|
1309
|
+
: lock_{!parent ? LockType{} : doLock(parent->mutex_)} {}
|
|
1310
|
+
|
|
1311
|
+
/**
|
|
1312
|
+
* Takes a Synchronized<T> and attempts to lock it, within the specified
|
|
1313
|
+
* timeout.
|
|
1314
|
+
*
|
|
1315
|
+
* Blocks until the lock is acquired or until the specified timeout expires.
|
|
1316
|
+
* If the timeout expired without acquiring the lock, the LockedPtr will be
|
|
1317
|
+
* null, and LockedPtr::isNull() will return true.
|
|
1318
|
+
*/
|
|
1319
|
+
template <class Rep, class Period>
|
|
1320
|
+
LockedPtr(
|
|
1321
|
+
SynchronizedType* parent,
|
|
1322
|
+
const std::chrono::duration<Rep, Period>& timeout)
|
|
1323
|
+
: lock_{parent ? LockType{parent->mutex_, timeout} : LockType{}} {}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Move constructor.
|
|
1327
|
+
*/
|
|
1328
|
+
LockedPtr(LockedPtr&& rhs) noexcept = default;
|
|
1329
|
+
template <
|
|
1330
|
+
typename Type = SynchronizedType,
|
|
1331
|
+
std::enable_if_t<std::is_const<Type>::value, int> = 0>
|
|
1332
|
+
/* implicit */ LockedPtr(LockedPtr<Synchronized, LockPolicy>&& rhs) noexcept
|
|
1333
|
+
: lock_{std::move(rhs.lock_)} {}
|
|
1334
|
+
template <
|
|
1335
|
+
typename LockPolicyType,
|
|
1336
|
+
EnableIfSameLevel<LockPolicyType>* = nullptr>
|
|
1337
|
+
explicit LockedPtr(
|
|
1338
|
+
LockedPtr<SynchronizedType, LockPolicyType>&& other) noexcept
|
|
1339
|
+
: lock_{std::move(other.lock_)} {}
|
|
1340
|
+
template <
|
|
1341
|
+
typename Type = SynchronizedType,
|
|
1342
|
+
typename LockPolicyType,
|
|
1343
|
+
std::enable_if_t<std::is_const<Type>::value, int> = 0,
|
|
1344
|
+
EnableIfSameLevel<LockPolicyType>* = nullptr>
|
|
1345
|
+
explicit LockedPtr(LockedPtr<Synchronized, LockPolicyType>&& rhs) noexcept
|
|
1346
|
+
: lock_{std::move(rhs.lock_)} {}
|
|
1347
|
+
|
|
1348
|
+
/**
|
|
1349
|
+
* Move assignment operator.
|
|
1350
|
+
*/
|
|
1351
|
+
LockedPtr& operator=(LockedPtr&& rhs) noexcept = default;
|
|
1352
|
+
template <
|
|
1353
|
+
typename LockPolicyType,
|
|
1354
|
+
EnableIfSameLevel<LockPolicyType>* = nullptr>
|
|
1355
|
+
LockedPtr& operator=(
|
|
1356
|
+
LockedPtr<SynchronizedType, LockPolicyType>&& other) noexcept {
|
|
1357
|
+
lock_ = std::move(other.lock_);
|
|
1358
|
+
return *this;
|
|
1359
|
+
}
|
|
1360
|
+
template <
|
|
1361
|
+
typename Type = SynchronizedType,
|
|
1362
|
+
typename LockPolicyType,
|
|
1363
|
+
std::enable_if_t<std::is_const<Type>::value, int> = 0,
|
|
1364
|
+
EnableIfSameLevel<LockPolicyType>* = nullptr>
|
|
1365
|
+
LockedPtr& operator=(
|
|
1366
|
+
LockedPtr<Synchronized, LockPolicyType>&& other) noexcept {
|
|
1367
|
+
lock_ = std::move(other.lock_);
|
|
1368
|
+
return *this;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
/*
|
|
1372
|
+
* Copy constructor and assignment operator are deleted.
|
|
1373
|
+
*/
|
|
1374
|
+
LockedPtr(const LockedPtr& rhs) = delete;
|
|
1375
|
+
LockedPtr& operator=(const LockedPtr& rhs) = delete;
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* Destructor releases.
|
|
1379
|
+
*/
|
|
1380
|
+
~LockedPtr() = default;
|
|
1381
|
+
|
|
1382
|
+
/**
|
|
1383
|
+
* Access the underlying lock object.
|
|
1384
|
+
*/
|
|
1385
|
+
LockType& as_lock() noexcept { return lock_; }
|
|
1386
|
+
LockType const& as_lock() const noexcept { return lock_; }
|
|
1387
|
+
|
|
1388
|
+
/**
|
|
1389
|
+
* Check if this LockedPtr is uninitialized, or points to valid locked data.
|
|
1390
|
+
*
|
|
1391
|
+
* This method can be used to check if a timed-acquire operation succeeded.
|
|
1392
|
+
* If an acquire operation times out it will result in a null LockedPtr.
|
|
1393
|
+
*
|
|
1394
|
+
* A LockedPtr is always either null, or holds a lock to valid data.
|
|
1395
|
+
* Methods such as scopedUnlock() reset the LockedPtr to null for the
|
|
1396
|
+
* duration of the unlock.
|
|
1397
|
+
*/
|
|
1398
|
+
bool isNull() const { return !lock_.owns_lock(); }
|
|
1399
|
+
|
|
1400
|
+
/**
|
|
1401
|
+
* Explicit boolean conversion.
|
|
1402
|
+
*
|
|
1403
|
+
* Returns !isNull()
|
|
1404
|
+
*/
|
|
1405
|
+
explicit operator bool() const { return lock_.owns_lock(); }
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Access the locked data.
|
|
1409
|
+
*
|
|
1410
|
+
* This method should only be used if the LockedPtr is valid.
|
|
1411
|
+
*/
|
|
1412
|
+
CDataType* operator->() const { return std::addressof(parent()->datum_); }
|
|
1413
|
+
|
|
1414
|
+
/**
|
|
1415
|
+
* Access the locked data.
|
|
1416
|
+
*
|
|
1417
|
+
* This method should only be used if the LockedPtr is valid.
|
|
1418
|
+
*/
|
|
1419
|
+
CDataType& operator*() const { return parent()->datum_; }
|
|
1420
|
+
|
|
1421
|
+
void unlock() noexcept { lock_ = {}; }
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* Locks that allow concurrent access (shared, upgrade) force const
|
|
1425
|
+
* access with the standard accessors even if the Synchronized
|
|
1426
|
+
* object is non-const.
|
|
1427
|
+
*
|
|
1428
|
+
* In some cases non-const access can be needed, for example:
|
|
1429
|
+
*
|
|
1430
|
+
* - Under an upgrade lock, to get references that will be mutated
|
|
1431
|
+
* after upgrading to a write lock.
|
|
1432
|
+
*
|
|
1433
|
+
* - Under an read lock, if some mutating operations on the data
|
|
1434
|
+
* are thread safe (e.g. mutating the value in an associative
|
|
1435
|
+
* container with reference stability).
|
|
1436
|
+
*
|
|
1437
|
+
* asNonConstUnsafe() returns a non-const reference to the data if
|
|
1438
|
+
* the parent Synchronized object was non-const at the point of lock
|
|
1439
|
+
* acquisition.
|
|
1440
|
+
*/
|
|
1441
|
+
template <typename = void>
|
|
1442
|
+
DataType& asNonConstUnsafe() const {
|
|
1443
|
+
static_assert(
|
|
1444
|
+
AllowsConcurrentAccess && !std::is_const<SynchronizedType>::value,
|
|
1445
|
+
"asNonConstUnsafe() is only available on non-exclusive locks"
|
|
1446
|
+
" acquired in a non-const context");
|
|
1447
|
+
|
|
1448
|
+
return parent()->datum_;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* Temporarily unlock the LockedPtr, and reset it to null.
|
|
1453
|
+
*
|
|
1454
|
+
* Returns an helper object that will re-lock and restore the LockedPtr when
|
|
1455
|
+
* the helper is destroyed. The LockedPtr may not be dereferenced for as
|
|
1456
|
+
* long as this helper object exists.
|
|
1457
|
+
*/
|
|
1458
|
+
ScopedUnlocker<SynchronizedType, LockPolicy> scopedUnlock() {
|
|
1459
|
+
return ScopedUnlocker<SynchronizedType, LockPolicy>(this);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/***************************************************************************
|
|
1463
|
+
* Upgrade lock methods.
|
|
1464
|
+
* These are disabled via SFINAE when the mutex is not an upgrade mutex.
|
|
1465
|
+
**************************************************************************/
|
|
1466
|
+
/**
|
|
1467
|
+
* Move the locked ptr from an upgrade state to an exclusive state. The
|
|
1468
|
+
* current lock is left in a null state.
|
|
1469
|
+
*/
|
|
1470
|
+
template <
|
|
1471
|
+
typename SyncType = SynchronizedType,
|
|
1472
|
+
decltype(void(std::declval<typename SyncType::MutexType&>()
|
|
1473
|
+
.lock_upgrade()))* = nullptr>
|
|
1474
|
+
LockedPtr<SynchronizedType, detail::SynchronizedLockPolicyExclusive>
|
|
1475
|
+
moveFromUpgradeToWrite() {
|
|
1476
|
+
static_assert(std::is_same<SyncType, SynchronizedType>::value, "mismatch");
|
|
1477
|
+
return transition_to_unique_lock(lock_);
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* Move the locked ptr from an exclusive state to an upgrade state. The
|
|
1482
|
+
* current lock is left in a null state.
|
|
1483
|
+
*/
|
|
1484
|
+
template <
|
|
1485
|
+
typename SyncType = SynchronizedType,
|
|
1486
|
+
decltype(void(std::declval<typename SyncType::MutexType&>()
|
|
1487
|
+
.lock_upgrade()))* = nullptr>
|
|
1488
|
+
LockedPtr<SynchronizedType, detail::SynchronizedLockPolicyUpgrade>
|
|
1489
|
+
moveFromWriteToUpgrade() {
|
|
1490
|
+
static_assert(std::is_same<SyncType, SynchronizedType>::value, "mismatch");
|
|
1491
|
+
return transition_to_upgrade_lock(lock_);
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
/**
|
|
1495
|
+
* Move the locked ptr from an upgrade state to a shared state. The
|
|
1496
|
+
* current lock is left in a null state.
|
|
1497
|
+
*/
|
|
1498
|
+
template <
|
|
1499
|
+
typename SyncType = SynchronizedType,
|
|
1500
|
+
decltype(void(std::declval<typename SyncType::MutexType&>()
|
|
1501
|
+
.lock_upgrade()))* = nullptr>
|
|
1502
|
+
LockedPtr<SynchronizedType, detail::SynchronizedLockPolicyShared>
|
|
1503
|
+
moveFromUpgradeToRead() {
|
|
1504
|
+
static_assert(std::is_same<SyncType, SynchronizedType>::value, "mismatch");
|
|
1505
|
+
return transition_to_shared_lock(lock_);
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Move the locked ptr from an exclusive state to a shared state. The
|
|
1510
|
+
* current lock is left in a null state.
|
|
1511
|
+
*/
|
|
1512
|
+
template <
|
|
1513
|
+
typename SyncType = SynchronizedType,
|
|
1514
|
+
decltype(void(std::declval<typename SyncType::MutexType&>()
|
|
1515
|
+
.lock_shared()))* = nullptr>
|
|
1516
|
+
LockedPtr<SynchronizedType, detail::SynchronizedLockPolicyShared>
|
|
1517
|
+
moveFromWriteToRead() {
|
|
1518
|
+
static_assert(std::is_same<SyncType, SynchronizedType>::value, "mismatch");
|
|
1519
|
+
return transition_to_shared_lock(lock_);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
SynchronizedType* parent() const {
|
|
1523
|
+
using simulacrum = typename SynchronizedType::Simulacrum;
|
|
1524
|
+
static_assert(sizeof(simulacrum) == sizeof(SynchronizedType), "mismatch");
|
|
1525
|
+
static_assert(alignof(simulacrum) == alignof(SynchronizedType), "mismatch");
|
|
1526
|
+
auto off = offsetof(simulacrum, mutex_);
|
|
1527
|
+
const auto raw = reinterpret_cast<char*>(lock_.mutex());
|
|
1528
|
+
return reinterpret_cast<SynchronizedType*>(raw - (raw ? off : 0));
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
private:
|
|
1532
|
+
/* implicit */ LockedPtr(LockType lock) noexcept : lock_{std::move(lock)} {}
|
|
1533
|
+
|
|
1534
|
+
template <typename LP>
|
|
1535
|
+
static constexpr bool is_try =
|
|
1536
|
+
LP::method == detail::SynchronizedMutexMethod::TryLock;
|
|
1537
|
+
|
|
1538
|
+
template <
|
|
1539
|
+
typename MT,
|
|
1540
|
+
typename LT = LockType,
|
|
1541
|
+
typename LP = LockPolicy,
|
|
1542
|
+
std::enable_if_t<is_try<LP>, int> = 0>
|
|
1543
|
+
FOLLY_ERASE static LT doLock(MT& mutex) {
|
|
1544
|
+
return LT{mutex, std::try_to_lock};
|
|
1545
|
+
}
|
|
1546
|
+
template <
|
|
1547
|
+
typename MT,
|
|
1548
|
+
typename LT = LockType,
|
|
1549
|
+
typename LP = LockPolicy,
|
|
1550
|
+
std::enable_if_t<!is_try<LP>, int> = 0>
|
|
1551
|
+
FOLLY_ERASE static LT doLock(MT& mutex) {
|
|
1552
|
+
return LT{mutex};
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
void releaseLock() noexcept {
|
|
1556
|
+
DCHECK(lock_.owns_lock());
|
|
1557
|
+
lock_ = {};
|
|
1558
|
+
}
|
|
1559
|
+
void reacquireLock(SynchronizedType* parent) {
|
|
1560
|
+
DCHECK(parent);
|
|
1561
|
+
DCHECK(!lock_.owns_lock());
|
|
1562
|
+
lock_ = doLock(parent->mutex_);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
LockType lock_;
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* Helper functions that should be passed to either a lock() or synchronized()
|
|
1570
|
+
* invocation, these return implementation defined structs that will be used
|
|
1571
|
+
* to lock the synchronized instance appropriately.
|
|
1572
|
+
*
|
|
1573
|
+
* lock(wlock(one), rlock(two), wlock(three));
|
|
1574
|
+
* synchronized([](auto one, two) { ... }, wlock(one), rlock(two));
|
|
1575
|
+
*
|
|
1576
|
+
* For example in the above rlock() produces an implementation defined read
|
|
1577
|
+
* locking helper instance and wlock() a write locking helper
|
|
1578
|
+
*
|
|
1579
|
+
* Subsequent arguments passed to these locking helpers, after the first, will
|
|
1580
|
+
* be passed by const-ref to the corresponding function on the synchronized
|
|
1581
|
+
* instance. This means that if the function accepts these parameters by
|
|
1582
|
+
* value, they will be copied. Note that it is not necessary that the primary
|
|
1583
|
+
* locking function will be invoked at all (for eg. the implementation might
|
|
1584
|
+
* just invoke the try*Lock() method)
|
|
1585
|
+
*
|
|
1586
|
+
* // Try to acquire the lock for one second
|
|
1587
|
+
* synchronized([](auto) { ... }, wlock(one, 1s));
|
|
1588
|
+
*
|
|
1589
|
+
* // The timed lock acquire might never actually be called, if it is not
|
|
1590
|
+
* // needed by the underlying deadlock avoiding algorithm
|
|
1591
|
+
* synchronized([](auto, auto) { ... }, rlock(one), wlock(two, 1s));
|
|
1592
|
+
*
|
|
1593
|
+
* Note that the arguments passed to to *lock() calls will be passed by
|
|
1594
|
+
* const-ref to the function invocation, as the implementation might use them
|
|
1595
|
+
* many times
|
|
1596
|
+
*/
|
|
1597
|
+
template <typename D, typename M, typename... Args>
|
|
1598
|
+
auto wlock(Synchronized<D, M>& synchronized, Args&&... args) {
|
|
1599
|
+
return detail::wlock(synchronized, std::forward<Args>(args)...);
|
|
1600
|
+
}
|
|
1601
|
+
template <typename D, typename M, typename... Args>
|
|
1602
|
+
auto wlock(const Synchronized<D, M>& synchronized, Args&&... args) {
|
|
1603
|
+
return detail::wlock(synchronized, std::forward<Args>(args)...);
|
|
1604
|
+
}
|
|
1605
|
+
template <typename Data, typename Mutex, typename... Args>
|
|
1606
|
+
auto rlock(const Synchronized<Data, Mutex>& synchronized, Args&&... args) {
|
|
1607
|
+
return detail::rlock(synchronized, std::forward<Args>(args)...);
|
|
1608
|
+
}
|
|
1609
|
+
template <typename D, typename M, typename... Args>
|
|
1610
|
+
auto ulock(Synchronized<D, M>& synchronized, Args&&... args) {
|
|
1611
|
+
return detail::ulock(synchronized, std::forward<Args>(args)...);
|
|
1612
|
+
}
|
|
1613
|
+
template <typename D, typename M, typename... Args>
|
|
1614
|
+
auto lock(Synchronized<D, M>& synchronized, Args&&... args) {
|
|
1615
|
+
return detail::lock(synchronized, std::forward<Args>(args)...);
|
|
1616
|
+
}
|
|
1617
|
+
template <typename D, typename M, typename... Args>
|
|
1618
|
+
auto lock(const Synchronized<D, M>& synchronized, Args&&... args) {
|
|
1619
|
+
return detail::lock(synchronized, std::forward<Args>(args)...);
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* Acquire locks for multiple Synchronized<> objects, in a deadlock-safe
|
|
1624
|
+
* manner.
|
|
1625
|
+
*
|
|
1626
|
+
* Wrap the synchronized instances with the appropriate locking strategy by
|
|
1627
|
+
* using one of the four strategies - folly::lock (exclusive acquire for
|
|
1628
|
+
* exclusive only mutexes), folly::rlock (shared acquire for shareable
|
|
1629
|
+
* mutexes), folly::wlock (exclusive acquire for shareable mutexes) or
|
|
1630
|
+
* folly::ulock (upgrade acquire for upgrade mutexes) (see above)
|
|
1631
|
+
*
|
|
1632
|
+
* The locks will be acquired and the passed callable will be invoked with the
|
|
1633
|
+
* LockedPtr instances in the order that they were passed to the function
|
|
1634
|
+
*/
|
|
1635
|
+
template <typename Func, typename... SynchronizedLockers>
|
|
1636
|
+
decltype(auto) synchronized(Func&& func, SynchronizedLockers&&... lockers) {
|
|
1637
|
+
return apply(
|
|
1638
|
+
std::forward<Func>(func),
|
|
1639
|
+
lock(std::forward<SynchronizedLockers>(lockers)...));
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* Acquire locks on many lockables or synchronized instances in such a way
|
|
1644
|
+
* that the sequence of calls within the function does not cause deadlocks.
|
|
1645
|
+
*
|
|
1646
|
+
* This can often result in a performance boost as compared to simply
|
|
1647
|
+
* acquiring your locks in an ordered manner. Even for very simple cases.
|
|
1648
|
+
* The algorithm tried to adjust to contention by blocking on the mutex it
|
|
1649
|
+
* thinks is the best fit, leaving all other mutexes open to be locked by
|
|
1650
|
+
* other threads. See the benchmarks in folly/test/SynchronizedBenchmark.cpp
|
|
1651
|
+
* for more
|
|
1652
|
+
*
|
|
1653
|
+
* This works differently as compared to the locking algorithm in libstdc++
|
|
1654
|
+
* and is the recommended way to acquire mutexes in a generic order safe
|
|
1655
|
+
* manner. Performance benchmarks show that this does better than the one in
|
|
1656
|
+
* libstdc++ even for the simple cases
|
|
1657
|
+
*
|
|
1658
|
+
* Usage is the same as std::lock() for arbitrary lockables
|
|
1659
|
+
*
|
|
1660
|
+
* folly::lock(one, two, three);
|
|
1661
|
+
*
|
|
1662
|
+
* To make it work with folly::Synchronized you have to specify how you want
|
|
1663
|
+
* the locks to be acquired, use the folly::wlock(), folly::rlock(),
|
|
1664
|
+
* folly::ulock() and folly::lock() helpers defined below
|
|
1665
|
+
*
|
|
1666
|
+
* auto [one, two] = lock(folly::wlock(a), folly::rlock(b));
|
|
1667
|
+
*
|
|
1668
|
+
* Note that you can/must avoid the folly:: namespace prefix on the lock()
|
|
1669
|
+
* function if you use the helpers, ADL lookup is done to find the lock function
|
|
1670
|
+
*
|
|
1671
|
+
* This will execute the deadlock avoidance algorithm and acquire a write lock
|
|
1672
|
+
* for a and a read lock for b
|
|
1673
|
+
*/
|
|
1674
|
+
template <typename LockableOne, typename LockableTwo, typename... Lockables>
|
|
1675
|
+
void lock(LockableOne& one, LockableTwo& two, Lockables&... lockables) {
|
|
1676
|
+
auto locker = [](auto& lockable) {
|
|
1677
|
+
using Lockable = std::remove_reference_t<decltype(lockable)>;
|
|
1678
|
+
return detail::makeSynchronizedLocker(
|
|
1679
|
+
lockable,
|
|
1680
|
+
[](auto& l) { return std::unique_lock<Lockable>{l}; },
|
|
1681
|
+
[](auto& l) {
|
|
1682
|
+
return std::unique_lock<Lockable>{l, std::try_to_lock};
|
|
1683
|
+
});
|
|
1684
|
+
};
|
|
1685
|
+
auto locks = lock(locker(one), locker(two), locker(lockables)...);
|
|
1686
|
+
|
|
1687
|
+
// release ownership of the locks from the RAII lock wrapper returned by the
|
|
1688
|
+
// function above
|
|
1689
|
+
for_each(locks, [&](auto& lock) { lock.release(); });
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
/**
|
|
1693
|
+
* Acquire locks for multiple Synchronized<T> objects, in a deadlock-safe
|
|
1694
|
+
* manner.
|
|
1695
|
+
*
|
|
1696
|
+
* The locks are acquired in order from lowest address to highest address.
|
|
1697
|
+
* (Note that this is not necessarily the same algorithm used by std::lock().)
|
|
1698
|
+
* For parameters that are const and support shared locks, a read lock is
|
|
1699
|
+
* acquired. Otherwise an exclusive lock is acquired.
|
|
1700
|
+
*
|
|
1701
|
+
* use lock() with folly::wlock(), folly::rlock() and folly::ulock() for
|
|
1702
|
+
* arbitrary locking without causing a deadlock (as much as possible), with the
|
|
1703
|
+
* same effects as std::lock()
|
|
1704
|
+
*/
|
|
1705
|
+
template <class Sync1, class Sync2>
|
|
1706
|
+
std::tuple<detail::LockedPtrType<Sync1>, detail::LockedPtrType<Sync2>>
|
|
1707
|
+
acquireLocked(Sync1& l1, Sync2& l2) {
|
|
1708
|
+
if (static_cast<const void*>(&l1) < static_cast<const void*>(&l2)) {
|
|
1709
|
+
auto p1 = l1.contextualLock();
|
|
1710
|
+
auto p2 = l2.contextualLock();
|
|
1711
|
+
return std::make_tuple(std::move(p1), std::move(p2));
|
|
1712
|
+
} else {
|
|
1713
|
+
auto p2 = l2.contextualLock();
|
|
1714
|
+
auto p1 = l1.contextualLock();
|
|
1715
|
+
return std::make_tuple(std::move(p1), std::move(p2));
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* A version of acquireLocked() that returns a std::pair rather than a
|
|
1721
|
+
* std::tuple, which is easier to use in many places.
|
|
1722
|
+
*/
|
|
1723
|
+
template <class Sync1, class Sync2>
|
|
1724
|
+
std::pair<detail::LockedPtrType<Sync1>, detail::LockedPtrType<Sync2>>
|
|
1725
|
+
acquireLockedPair(Sync1& l1, Sync2& l2) {
|
|
1726
|
+
auto lockedPtrs = acquireLocked(l1, l2);
|
|
1727
|
+
return {
|
|
1728
|
+
std::move(std::get<0>(lockedPtrs)), std::move(std::get<1>(lockedPtrs))};
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
/************************************************************************
|
|
1732
|
+
* NOTE: All APIs below this line will be deprecated in upcoming diffs.
|
|
1733
|
+
************************************************************************/
|
|
1734
|
+
|
|
1735
|
+
// Non-member swap primitive
|
|
1736
|
+
template <class T, class M>
|
|
1737
|
+
void swap(Synchronized<T, M>& lhs, Synchronized<T, M>& rhs) {
|
|
1738
|
+
lhs.swap(rhs);
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
/**
|
|
1742
|
+
* Disambiguate the name var by concatenating the line number of the original
|
|
1743
|
+
* point of expansion. This avoids shadowing warnings for nested
|
|
1744
|
+
* SYNCHRONIZEDs. The name is consistent if used multiple times within
|
|
1745
|
+
* another macro.
|
|
1746
|
+
* Only for internal use.
|
|
1747
|
+
*/
|
|
1748
|
+
#define SYNCHRONIZED_VAR(var) FB_CONCATENATE(SYNCHRONIZED_##var##_, __LINE__)
|
|
1749
|
+
|
|
1750
|
+
namespace detail {
|
|
1751
|
+
struct [[deprecated(
|
|
1752
|
+
"use explicit lock(), wlock(), or rlock() instead")]] SYNCHRONIZED_macro_is_deprecated {
|
|
1753
|
+
};
|
|
1754
|
+
} // namespace detail
|
|
1755
|
+
|
|
1756
|
+
/**
|
|
1757
|
+
* NOTE: This API is deprecated. Use lock(), wlock(), rlock() or the withLock
|
|
1758
|
+
* functions instead. In the future it will be marked with a deprecation
|
|
1759
|
+
* attribute to emit build-time warnings, and then it will be removed entirely.
|
|
1760
|
+
*
|
|
1761
|
+
* SYNCHRONIZED is the main facility that makes Synchronized<T>
|
|
1762
|
+
* helpful. It is a pseudo-statement that introduces a scope where the
|
|
1763
|
+
* object is locked. Inside that scope you get to access the unadorned
|
|
1764
|
+
* datum.
|
|
1765
|
+
*
|
|
1766
|
+
* Example:
|
|
1767
|
+
*
|
|
1768
|
+
* Synchronized<vector<int>> svector;
|
|
1769
|
+
* ...
|
|
1770
|
+
* SYNCHRONIZED (svector) { ... use svector as a vector<int> ... }
|
|
1771
|
+
* or
|
|
1772
|
+
* SYNCHRONIZED (v, svector) { ... use v as a vector<int> ... }
|
|
1773
|
+
*
|
|
1774
|
+
* Refer to folly/docs/Synchronized.md for a detailed explanation and more
|
|
1775
|
+
* examples.
|
|
1776
|
+
*/
|
|
1777
|
+
#define SYNCHRONIZED(...) \
|
|
1778
|
+
FOLLY_PUSH_WARNING \
|
|
1779
|
+
FOLLY_GNU_DISABLE_WARNING("-Wshadow") \
|
|
1780
|
+
FOLLY_MSVC_DISABLE_WARNING(4189) /* initialized but unreferenced */ \
|
|
1781
|
+
FOLLY_MSVC_DISABLE_WARNING(4456) /* declaration hides local */ \
|
|
1782
|
+
FOLLY_MSVC_DISABLE_WARNING(4457) /* declaration hides parameter */ \
|
|
1783
|
+
FOLLY_MSVC_DISABLE_WARNING(4458) /* declaration hides member */ \
|
|
1784
|
+
FOLLY_MSVC_DISABLE_WARNING(4459) /* declaration hides global */ \
|
|
1785
|
+
FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS \
|
|
1786
|
+
if (bool SYNCHRONIZED_VAR(state) = false) { \
|
|
1787
|
+
(void)::folly::detail::SYNCHRONIZED_macro_is_deprecated{}; \
|
|
1788
|
+
} else \
|
|
1789
|
+
for (auto SYNCHRONIZED_VAR(lockedPtr) = \
|
|
1790
|
+
(FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).contextualLock(); \
|
|
1791
|
+
!SYNCHRONIZED_VAR(state); \
|
|
1792
|
+
SYNCHRONIZED_VAR(state) = true) \
|
|
1793
|
+
for (auto& FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)) = \
|
|
1794
|
+
*SYNCHRONIZED_VAR(lockedPtr).operator->(); \
|
|
1795
|
+
!SYNCHRONIZED_VAR(state); \
|
|
1796
|
+
SYNCHRONIZED_VAR(state) = true) \
|
|
1797
|
+
FOLLY_POP_WARNING
|
|
1798
|
+
|
|
1799
|
+
/**
|
|
1800
|
+
* NOTE: This API is deprecated. Use lock(), wlock(), rlock() or the withLock
|
|
1801
|
+
* functions instead. In the future it will be marked with a deprecation
|
|
1802
|
+
* attribute to emit build-time warnings, and then it will be removed entirely.
|
|
1803
|
+
*
|
|
1804
|
+
* Similar to SYNCHRONIZED, but only uses a read lock.
|
|
1805
|
+
*/
|
|
1806
|
+
#define SYNCHRONIZED_CONST(...) \
|
|
1807
|
+
SYNCHRONIZED( \
|
|
1808
|
+
FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)), \
|
|
1809
|
+
std::as_const(FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))))
|
|
1810
|
+
|
|
1811
|
+
/**
|
|
1812
|
+
* NOTE: This API is deprecated. Use lock(), wlock(), rlock() or the withLock
|
|
1813
|
+
* functions instead. In the future it will be marked with a deprecation
|
|
1814
|
+
* attribute to emit build-time warnings, and then it will be removed entirely.
|
|
1815
|
+
*
|
|
1816
|
+
* Synchronizes two Synchronized objects (they may encapsulate
|
|
1817
|
+
* different data). Synchronization is done in increasing address of
|
|
1818
|
+
* object order, so there is no deadlock risk.
|
|
1819
|
+
*/
|
|
1820
|
+
#define SYNCHRONIZED_DUAL(n1, e1, n2, e2) \
|
|
1821
|
+
if (bool SYNCHRONIZED_VAR(state) = false) { \
|
|
1822
|
+
(void)::folly::detail::SYNCHRONIZED_macro_is_deprecated{}; \
|
|
1823
|
+
} else \
|
|
1824
|
+
for (auto SYNCHRONIZED_VAR(ptrs) = acquireLockedPair(e1, e2); \
|
|
1825
|
+
!SYNCHRONIZED_VAR(state); \
|
|
1826
|
+
SYNCHRONIZED_VAR(state) = true) \
|
|
1827
|
+
for (auto& n1 = *SYNCHRONIZED_VAR(ptrs).first; !SYNCHRONIZED_VAR(state); \
|
|
1828
|
+
SYNCHRONIZED_VAR(state) = true) \
|
|
1829
|
+
for (auto& n2 = *SYNCHRONIZED_VAR(ptrs).second; \
|
|
1830
|
+
!SYNCHRONIZED_VAR(state); \
|
|
1831
|
+
SYNCHRONIZED_VAR(state) = true)
|
|
1832
|
+
|
|
1833
|
+
} /* namespace folly */
|