/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @author: Andrei Alexandrescu (andrei.alexandrescu@fb.com)
*/
-#ifndef SYNCHRONIZED_H_
-#define SYNCHRONIZED_H_
+#pragma once
#include <type_traits>
#include <mutex>
#include <boost/thread.hpp>
#include <folly/Preprocessor.h>
+#include <folly/SharedMutex.h>
#include <folly/Traits.h>
namespace folly {
* refer to the namespace detail below, which implements the
* primitives for mutexes in std and boost.
*/
-template <class T, class Mutex = boost::shared_mutex>
+template <class T, class Mutex = SharedMutex>
struct Synchronized {
/**
* Default constructor leaves both members call their own default
explicit Synchronized(T&& rhs) noexcept(nxMoveCtor)
: datum_(std::move(rhs)) {}
+ /**
+ * Lets you construct non-movable types in-place. Use the constexpr
+ * instance `construct_in_place` as the first argument.
+ */
+ template <typename... Args>
+ explicit Synchronized(construct_in_place_t, Args&&... args)
+ : datum_(std::forward<Args>(args)...) {}
+
/**
* The canonical assignment operator only assigns the data, NOT the
* mutex. It locks the two objects in ascending order of their
* Refer to folly/docs/Synchronized.md for a detailed explanation and more
* examples.
*/
-#define SYNCHRONIZED(...) \
- if (bool SYNCHRONIZED_state = false) {} else \
- for (auto SYNCHRONIZED_lockedPtr = \
- (FB_ARG_2_OR_1(__VA_ARGS__)).operator->(); \
- !SYNCHRONIZED_state; SYNCHRONIZED_state = true) \
- for (auto& FB_ARG_1(__VA_ARGS__) = \
- *SYNCHRONIZED_lockedPtr.operator->(); \
- !SYNCHRONIZED_state; SYNCHRONIZED_state = true)
-
-#define TIMED_SYNCHRONIZED(timeout, ...) \
- if (bool SYNCHRONIZED_state = false) {} else \
- for (auto SYNCHRONIZED_lockedPtr = \
- (FB_ARG_2_OR_1(__VA_ARGS__)).timedAcquire(timeout); \
- !SYNCHRONIZED_state; SYNCHRONIZED_state = true) \
- for (auto FB_ARG_1(__VA_ARGS__) = \
- SYNCHRONIZED_lockedPtr.operator->(); \
- !SYNCHRONIZED_state; SYNCHRONIZED_state = true)
+#define SYNCHRONIZED(...) \
+ FOLLY_PUSH_WARNING \
+ FOLLY_GCC_DISABLE_WARNING(shadow) \
+ if (bool SYNCHRONIZED_state = false) { \
+ } else \
+ for (auto SYNCHRONIZED_lockedPtr = \
+ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).operator->(); \
+ !SYNCHRONIZED_state; \
+ SYNCHRONIZED_state = true) \
+ for (auto& FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)) = \
+ *SYNCHRONIZED_lockedPtr.operator->(); \
+ !SYNCHRONIZED_state; \
+ SYNCHRONIZED_state = true) \
+ FOLLY_POP_WARNING
+
+#define TIMED_SYNCHRONIZED(timeout, ...) \
+ if (bool SYNCHRONIZED_state = false) { \
+ } else \
+ for (auto SYNCHRONIZED_lockedPtr = \
+ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).timedAcquire(timeout); \
+ !SYNCHRONIZED_state; \
+ SYNCHRONIZED_state = true) \
+ for (auto FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)) = \
+ SYNCHRONIZED_lockedPtr.operator->(); \
+ !SYNCHRONIZED_state; \
+ SYNCHRONIZED_state = true)
/**
* Similar to SYNCHRONIZED, but only uses a read lock.
*/
-#define SYNCHRONIZED_CONST(...) \
- SYNCHRONIZED(FB_ARG_1(__VA_ARGS__), \
- (FB_ARG_2_OR_1(__VA_ARGS__)).asConst())
+#define SYNCHRONIZED_CONST(...) \
+ SYNCHRONIZED( \
+ FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)), \
+ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).asConst())
/**
* Similar to TIMED_SYNCHRONIZED, but only uses a read lock.
*/
-#define TIMED_SYNCHRONIZED_CONST(timeout, ...) \
- TIMED_SYNCHRONIZED(timeout, FB_ARG_1(__VA_ARGS__), \
- (FB_ARG_2_OR_1(__VA_ARGS__)).asConst())
+#define TIMED_SYNCHRONIZED_CONST(timeout, ...) \
+ TIMED_SYNCHRONIZED( \
+ timeout, \
+ FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)), \
+ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).asConst())
/**
* Temporarily disables synchronization inside a SYNCHRONIZED block.
for (decltype(SYNCHRONIZED_lockedPtr.typeHackDoNotUse()) \
SYNCHRONIZED_state3(&SYNCHRONIZED_lockedPtr); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true) \
- for (auto name = *SYNCHRONIZED_state3.operator->(); \
+ for (auto& name = *SYNCHRONIZED_state3.operator->(); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true)
/**
else
} /* namespace folly */
-
-#endif // SYNCHRONIZED_H_