diff --git a/cpp/platform/impl/windows/BUILD b/cpp/platform/impl/windows/BUILD index f0554a0c..a62ca186 100644 --- a/cpp/platform/impl/windows/BUILD +++ b/cpp/platform/impl/windows/BUILD @@ -98,9 +98,7 @@ cc_library( "bluetooth_classic_medium.cc", "bluetooth_classic_server_socket.cc", "bluetooth_classic_socket.cc", - "condition_variable.cc", "executor.cc", - "mutex.cc", "platform.cc", "scheduled_executor.cc", "submittable_executor.cc", @@ -170,12 +168,10 @@ cc_test( srcs = [ "atomic_boolean_test.cc", "atomic_reference_test.cc", - "condition_variable_test.cc", "count_down_latch_test.cc", "crypto_test.cc", "executor_test.cc", "input_file_test.cc", - "mutex_test.cc", "output_file_test.cc", "scheduled_executor_test.cc", "submittable_executor_test.cc", diff --git a/cpp/platform/impl/windows/condition_variable.h b/cpp/platform/impl/windows/condition_variable.h index 97f9025d..b28c0b22 100644 --- a/cpp/platform/impl/windows/condition_variable.h +++ b/cpp/platform/impl/windows/condition_variable.h @@ -11,10 +11,8 @@ // 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. - #ifndef PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_ #define PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_ - #include #include #include @@ -23,46 +21,35 @@ #include "platform/api/condition_variable.h" #include "platform/impl/windows/mutex.h" +#include "platform/public/mutex.h" namespace location { namespace nearby { namespace windows { -// The ConditionVariable class is a synchronization primitive that can be used -// to block a thread, or multiple threads at the same time, until another thread -// both modifies a shared variable (the condition), and notifies the -// ConditionVariable. class ConditionVariable : public api::ConditionVariable { public: - ConditionVariable(api::Mutex* mutex); - + explicit ConditionVariable(api::Mutex* mutex) + : mutex_(&(static_cast(mutex))->mutex_) {} ~ConditionVariable() override = default; - // Notifies all the waiters that condition state has changed. - void Notify() override; + Exception Wait() override { + cond_var_.Wait(mutex_); + return {Exception::kSuccess}; + } - // Waits indefinitely for Notify to be called. - // May return prematurely in case of interrupt, if supported by platform. - // Returns kSuccess, or kInterrupted on interrupt. - Exception Wait() override; + Exception Wait(absl::Duration timeout) override { + cond_var_.WaitWithTimeout(mutex_, timeout); + return {Exception::kSuccess}; + } - // Waits while timeout has not expired for Notify to be called. - // May return prematurely in case of interrupt, if supported by platform. - // Returns kSuccess, or kInterrupted on interrupt. - Exception Wait(absl::Duration timeout) override; + void Notify() override { cond_var_.SignalAll(); } private: - location::nearby::windows::Mutex& mutex_; - - std::condition_variable condition_variable_actual_; - std::condition_variable& condition_variable_ = condition_variable_actual_; - - std::unique_lock lock; - CRITICAL_SECTION critical_section_; + absl::Mutex* mutex_; + absl::CondVar cond_var_; }; - } // namespace windows } // namespace nearby } // namespace location - #endif // PLATFORM_IMPL_WINDOWS_CONDITION_VARIABLE_H_ diff --git a/cpp/platform/impl/windows/mutex.h b/cpp/platform/impl/windows/mutex.h index e6cebe09..956b6720 100644 --- a/cpp/platform/impl/windows/mutex.h +++ b/cpp/platform/impl/windows/mutex.h @@ -11,10 +11,8 @@ // 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. - #ifndef PLATFORM_IMPL_WINDOWS_MUTEX_H_ #define PLATFORM_IMPL_WINDOWS_MUTEX_H_ - #include #include #include @@ -23,46 +21,49 @@ #include // NOLINT #include "absl/memory/memory.h" +#include "absl/synchronization/mutex.h" #include "platform/api/mutex.h" - namespace location { namespace nearby { namespace windows { // A lock is a tool for controlling access to a shared resource by multiple // threads. -// // https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html -class Mutex : public api::Mutex { +class ABSL_LOCKABLE Mutex : public api::Mutex { public: - Mutex(Mutex::Mode mode); - + explicit Mutex(Mode mode) : mode_(mode) {} ~Mutex() override = default; + Mutex(Mutex&&) = delete; + Mutex& operator=(Mutex&&) = delete; + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; - void Lock() override; + void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() override { + if (mode_ == Mode::kRegularNoCheck) mutex_.ForgetDeadlockInfo(); + if (mode_ == Mode::kRegular || mode_ == Mode::kRegularNoCheck) { + mutex_.Lock(); + } else { + recursive_mutex_.lock(); + } + } - void Unlock() override; - - std::mutex& GetWindowsMutex(); - - std::recursive_mutex& GetWindowsRecursiveMutex(); + void Unlock() ABSL_UNLOCK_FUNCTION() override { + if (mode_ == Mode::kRegular || mode_ == Mode::kRegularNoCheck) { + mutex_.Unlock(); + } else { + recursive_mutex_.unlock(); + } + } private: - Mutex::Mode mode_; - - std::mutex mutex_impl_; // The actual mutex allocation - std::mutex& mutex_ = - mutex_impl_; // This is passed to other windows functions, must be by - // reference to avoid ownership problems - std::recursive_mutex recursive_mutex_impl_; // The actual mutex allocation - std::recursive_mutex& recursive_mutex_ = - recursive_mutex_impl_; // This is passed to other windows functions, - // must be by reference to avoid ownership - // problems + friend class ConditionVariable; + absl::Mutex mutex_; + std::recursive_mutex recursive_mutex_; // The actual mutex allocation + Mode mode_; }; } // namespace windows } // namespace nearby } // namespace location - #endif // PLATFORM_IMPL_WINDOWS_MUTEX_H_