Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove PROTOBUF_MAYBE_CONSTEXPR and make the constructor constexpr ev… #8115

Merged
merged 1 commit into from
Dec 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/google/protobuf/map_field.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
12 changes: 0 additions & 12 deletions src/google/protobuf/port_def.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) \
Expand Down
1 change: 0 additions & 1 deletion src/google/protobuf/port_undef.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
33 changes: 28 additions & 5 deletions src/google/protobuf/stubs/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,47 @@ 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.
// May fail to crash when it should; will never crash when it should not.
void AssertHeld() const {}

private:
#ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
#if defined(_MSC_VER)
CallOnceInitializedMutex<std::mutex> mu_;
#elif defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP)
CallOnceInitializedMutex<CriticalSectionLock> mu_;
#else
std::mutex mu_;
#else // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
CriticalSectionLock mu_;
#endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
#endif
};

using Mutex = WrappedMutex;
Expand Down