Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
19fb89416f | ||
|
4a09d77a85 |
@ -329,7 +329,7 @@ class PROTOBUF_EXPORT MapFieldBase {
|
||||
// It uses a linker initialized mutex, so it is not compatible with regular
|
||||
// runtime instances.
|
||||
// Except in MSVC, where we can't have a constinit mutex.
|
||||
explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized)
|
||||
explicit constexpr MapFieldBase(ConstantInitialized)
|
||||
: arena_(nullptr),
|
||||
repeated_field_(nullptr),
|
||||
mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
|
||||
|
@ -148,9 +148,6 @@
|
||||
#ifdef PROTOBUF_CONSTINIT
|
||||
#error PROTOBUF_CONSTINIT was previously defined
|
||||
#endif
|
||||
#ifdef PROTOBUF_MAYBE_CONSTEXPR
|
||||
#error PROTOBUF_MAYBE_CONSTEXPR was previously defined
|
||||
#endif
|
||||
#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY
|
||||
#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined
|
||||
#endif
|
||||
@ -560,15 +557,6 @@
|
||||
#define PROTOBUF_CONSTINIT
|
||||
#endif
|
||||
|
||||
// Some constructors can't be constexpr under MSVC, but given that MSVC will not
|
||||
// do constant initialization of globals anyway we can omit `constexpr` from
|
||||
// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR
|
||||
#if defined(_MSC_VER)
|
||||
#define PROTOBUF_MAYBE_CONSTEXPR
|
||||
#else
|
||||
#define PROTOBUF_MAYBE_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
#define PROTOBUF_DISABLE_MSVC_UNION_WARNING \
|
||||
__pragma(warning(push)) \
|
||||
|
@ -75,7 +75,6 @@
|
||||
#undef PROTOBUF_DISABLE_MSVC_UNION_WARNING
|
||||
#undef PROTOBUF_ENABLE_MSVC_UNION_WARNING
|
||||
#undef PROTOBUF_CONSTINIT
|
||||
#undef PROTOBUF_MAYBE_CONSTEXPR
|
||||
#undef PROTOBUF_ATTRIBUTE_NO_DESTROY
|
||||
|
||||
// Restore macro that may have been #undef'd in port_def.inc.
|
||||
|
@ -90,12 +90,33 @@ class PROTOBUF_EXPORT CriticalSectionLock {
|
||||
|
||||
#endif
|
||||
|
||||
// In MSVC std::mutex does not have a constexpr constructor.
|
||||
// This wrapper makes the constructor constexpr.
|
||||
template <typename T>
|
||||
class CallOnceInitializedMutex {
|
||||
public:
|
||||
constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {}
|
||||
~CallOnceInitializedMutex() { get().~T(); }
|
||||
|
||||
void lock() { get().lock(); }
|
||||
void unlock() { get().unlock(); }
|
||||
|
||||
private:
|
||||
T& get() {
|
||||
std::call_once(flag_, [&] { ::new (static_cast<void*>(&buf_)) T(); });
|
||||
return reinterpret_cast<T&>(buf_);
|
||||
}
|
||||
|
||||
std::once_flag flag_;
|
||||
alignas(T) char buf_[sizeof(T)];
|
||||
};
|
||||
|
||||
// Mutex is a natural type to wrap. As both google and other organization have
|
||||
// specialized mutexes. gRPC also provides an injection mechanism for custom
|
||||
// mutexes.
|
||||
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
|
||||
public:
|
||||
WrappedMutex() = default;
|
||||
constexpr WrappedMutex() = default;
|
||||
void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
|
||||
void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
|
||||
// Crash if this Mutex is not held exclusively by this thread.
|
||||
@ -103,11 +124,13 @@ class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
|
||||
void AssertHeld() const {}
|
||||
|
||||
private:
|
||||
#ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
|
||||
std::mutex mu_;
|
||||
#else // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
|
||||
CriticalSectionLock mu_;
|
||||
#endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
|
||||
#if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP)
|
||||
CallOnceInitializedMutex<CriticalSectionLock> mu_ {};
|
||||
#elif defined(_MSC_VER)
|
||||
CallOnceInitializedMutex<std::mutex> mu_ {};
|
||||
#else
|
||||
std::mutex mu_ {};
|
||||
#endif
|
||||
};
|
||||
|
||||
using Mutex = WrappedMutex;
|
||||
|
Loading…
Reference in New Issue
Block a user