diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index efa6f2fec0..c7b1af9eba 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -136,6 +136,12 @@ set(common_SRCS src/variant.cc src/base64.cc) +if (MSVC) + set(mutex_SRCS src/mutex_windows.cc) +else() + set(mutex_SRCS src/mutex_pthread.cc) +endif() + set(invites_SRCS src/invites/cached_receiver.cc src/invites/invites_receiver_internal.cc) @@ -313,6 +319,7 @@ add_library(firebase_app STATIC ${log_HDRS} ${common_SRCS} ${invites_SRCS} + ${mutex_SRCS} ${app_platform_SRCS} ${internal_HDRS} ${utility_HDRS} diff --git a/app/src/mutex.h b/app/src/mutex.h index 9a3624d7c8..47a7172f92 100644 --- a/app/src/mutex.h +++ b/app/src/mutex.h @@ -16,17 +16,14 @@ #ifndef FIREBASE_APP_SRC_MUTEX_H_ #define FIREBASE_APP_SRC_MUTEX_H_ -#include #include "app/src/include/firebase/internal/platform.h" -#if !FIREBASE_PLATFORM_WINDOWS -#include -#else +#if FIREBASE_PLATFORM_WINDOWS #include -#endif // !FIREBASE_PLATFORM_WINDOWS - -#include "app/src/assert.h" +#else +#include +#endif // FIREBASE_PLATFORM_WINDOWS namespace firebase { @@ -39,100 +36,36 @@ class Mutex { kModeRecursive = (1 << 0), }; - Mutex() { Initialize(kModeRecursive); } + Mutex() : Mutex(kModeRecursive) {} - explicit Mutex(Mode mode) { Initialize(mode); } + explicit Mutex(Mode mode); - ~Mutex() { -#if !FIREBASE_PLATFORM_WINDOWS - int ret = pthread_mutex_destroy(&mutex_); - FIREBASE_ASSERT(ret == 0); - (void)ret; -#else - CloseHandle(synchronization_object_); -#endif // !FIREBASE_PLATFORM_WINDOWS - } - - void Acquire() { -#if !FIREBASE_PLATFORM_WINDOWS - int ret = pthread_mutex_lock(&mutex_); - if (ret == EINVAL) { - return; - } -#if defined(__APPLE__) - // Lock / unlock will fail in a static initializer on OSX and iOS. - FIREBASE_ASSERT(ret == 0 || ret == EINVAL); -#else - FIREBASE_ASSERT(ret == 0); -#endif // defined(__APPLE__) - (void)ret; -#else - DWORD ret = WaitForSingleObject(synchronization_object_, INFINITE); - FIREBASE_ASSERT(ret == WAIT_OBJECT_0); - (void)ret; -#endif // !FIREBASE_PLATFORM_WINDOWS - } - - void Release() { -#if !FIREBASE_PLATFORM_WINDOWS - int ret = pthread_mutex_unlock(&mutex_); -#if defined(__APPLE__) - // Lock / unlock will fail in a static initializer on OSX and iOS. - FIREBASE_ASSERT(ret == 0 || ret == EINVAL); -#else - FIREBASE_ASSERT(ret == 0); -#endif // defined(__APPLE__) - (void)ret; -#else - if (mode_ & kModeRecursive) { - ReleaseMutex(synchronization_object_); - } else { - ReleaseSemaphore(synchronization_object_, 1, 0); - } -#endif // !FIREBASE_PLATFORM_WINDOWS - } + ~Mutex(); + + // Acquires the lock for this mutex, blocking until it is available. + void Acquire(); + + // Releases the lock for this mutex acquired by a previous `Acquire()` call. + void Release(); // Returns the implementation-defined native mutex handle. // Used by firebase::Thread implementation. -#if !FIREBASE_PLATFORM_WINDOWS - pthread_mutex_t* native_handle() { return &mutex_; } -#else +#if FIREBASE_PLATFORM_WINDOWS HANDLE* native_handle() { return &synchronization_object_; } -#endif +#else + pthread_mutex_t* native_handle() { return &mutex_; } +#endif // FIREBASE_PLATFORM_WINDOWS private: Mutex(const Mutex&) = delete; Mutex& operator=(const Mutex&) = delete; - void Initialize(Mode mode) { -#if !FIREBASE_PLATFORM_WINDOWS - pthread_mutexattr_t attr; - int ret = pthread_mutexattr_init(&attr); - FIREBASE_ASSERT(ret == 0); - if (mode & kModeRecursive) { - ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - FIREBASE_ASSERT(ret == 0); - } - ret = pthread_mutex_init(&mutex_, &attr); - FIREBASE_ASSERT(ret == 0); - ret = pthread_mutexattr_destroy(&attr); - FIREBASE_ASSERT(ret == 0); -#else - mode_ = mode; - if (mode & kModeRecursive) { - synchronization_object_ = CreateMutex(nullptr, FALSE, nullptr); - } else { - synchronization_object_ = CreateSemaphore(nullptr, 1, 1, nullptr); - } -#endif // !FIREBASE_PLATFORM_WINDOWS - } - -#if !FIREBASE_PLATFORM_WINDOWS - pthread_mutex_t mutex_; -#else +#if FIREBASE_PLATFORM_WINDOWS HANDLE synchronization_object_; Mode mode_; -#endif // !FIREBASE_PLATFORM_WINDOWS +#else + pthread_mutex_t mutex_; +#endif // FIREBASE_PLATFORM_WINDOWS }; /// @brief Acquire and hold a /ref Mutex, while in scope. @@ -158,7 +91,6 @@ class MutexLock { Mutex* mutex_; }; -// NOLINTNEXTLINE - allow namespace overridden } // namespace firebase #endif // FIREBASE_APP_SRC_MUTEX_H_ diff --git a/app/src/mutex_pthread.cc b/app/src/mutex_pthread.cc new file mode 100644 index 0000000000..4e4850d8a9 --- /dev/null +++ b/app/src/mutex_pthread.cc @@ -0,0 +1,69 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "app/src/assert.h" +#include "app/src/mutex.h" + +namespace firebase { + +Mutex::Mutex(Mode mode) { + pthread_mutexattr_t attr; + int ret = pthread_mutexattr_init(&attr); + FIREBASE_ASSERT(ret == 0); + if (mode & kModeRecursive) { + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + FIREBASE_ASSERT(ret == 0); + } + ret = pthread_mutex_init(&mutex_, &attr); + FIREBASE_ASSERT(ret == 0); + ret = pthread_mutexattr_destroy(&attr); + FIREBASE_ASSERT(ret == 0); +} + +Mutex::~Mutex() { + int ret = pthread_mutex_destroy(&mutex_); + FIREBASE_ASSERT(ret == 0); + (void)ret; +} + +void Mutex::Acquire() { + int ret = pthread_mutex_lock(&mutex_); + if (ret == EINVAL) { + return; + } +#if defined(__APPLE__) + // Lock / unlock will fail in a static initializer on OSX and iOS. + FIREBASE_ASSERT(ret == 0 || ret == EINVAL); +#else + FIREBASE_ASSERT(ret == 0); +#endif // defined(__APPLE__) + (void)ret; +} + +void Mutex::Release() { + int ret = pthread_mutex_unlock(&mutex_); +#if defined(__APPLE__) + // Lock / unlock will fail in a static initializer on OSX and iOS. + FIREBASE_ASSERT(ret == 0 || ret == EINVAL); +#else + FIREBASE_ASSERT(ret == 0); +#endif // defined(__APPLE__) + (void)ret; +} + +} // namespace firebase diff --git a/app/src/mutex_windows.cc b/app/src/mutex_windows.cc new file mode 100644 index 0000000000..7429fbc881 --- /dev/null +++ b/app/src/mutex_windows.cc @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "app/src/assert.h" +#include "app/src/include/firebase/internal/platform.h" +#include "app/src/mutex.h" + +namespace firebase { + +Mutex::Mutex(Mode mode) : mode_(mode) { + if (mode & kModeRecursive) { + synchronization_object_ = CreateMutex(nullptr, FALSE, nullptr); + } else { + synchronization_object_ = CreateSemaphore(nullptr, 1, 1, nullptr); + } +} + +Mutex::~Mutex() { CloseHandle(synchronization_object_); } + +void Mutex::Acquire() { + DWORD ret = WaitForSingleObject(synchronization_object_, INFINITE); + FIREBASE_ASSERT(ret == WAIT_OBJECT_0); + (void)ret; +} + +void Mutex::Release() { + if (mode_ & kModeRecursive) { + ReleaseMutex(synchronization_object_); + } else { + ReleaseSemaphore(synchronization_object_, 1, 0); + } +} + +} // namespace firebase diff --git a/app/src/reference_counted_future_impl.h b/app/src/reference_counted_future_impl.h index 6e4e06043f..2c4b09673b 100644 --- a/app/src/reference_counted_future_impl.h +++ b/app/src/reference_counted_future_impl.h @@ -21,6 +21,7 @@ #include #include +#include "app/src/assert.h" #include "app/src/cleanup_notifier.h" #include "app/src/include/firebase/future.h" #include "app/src/include/firebase/internal/common.h" diff --git a/app/src/secure/user_secure_fake_internal.cc b/app/src/secure/user_secure_fake_internal.cc index f839021d8e..5271d16aff 100644 --- a/app/src/secure/user_secure_fake_internal.cc +++ b/app/src/secure/user_secure_fake_internal.cc @@ -15,6 +15,7 @@ #include "app/src/secure/user_secure_fake_internal.h" #include "app/src/include/firebase/internal/platform.h" +#include "app/src/log.h" #if FIREBASE_PLATFORM_WINDOWS #include diff --git a/app/src/secure/user_secure_windows_internal.cc b/app/src/secure/user_secure_windows_internal.cc index 38a20dd329..8da2d73c5e 100644 --- a/app/src/secure/user_secure_windows_internal.cc +++ b/app/src/secure/user_secure_windows_internal.cc @@ -17,6 +17,8 @@ #define NOMINMAX #include +#include "app/src/log.h" + namespace firebase { namespace app { namespace secure { diff --git a/database/src/desktop/persistence/noop_persistence_manager.cc b/database/src/desktop/persistence/noop_persistence_manager.cc index fc03826394..6f291a3e44 100644 --- a/database/src/desktop/persistence/noop_persistence_manager.cc +++ b/database/src/desktop/persistence/noop_persistence_manager.cc @@ -14,6 +14,8 @@ #include "database/src/desktop/persistence/noop_persistence_manager.h" +#include "app/src/assert.h" + #define VERIFY_INSIDE_TRANSACTION() \ FIREBASE_DEV_ASSERT_MESSAGE( \ this->inside_transaction_, \