1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_ 6 #define QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_ 7 8 #include "quiche_platform_impl/quiche_mutex_impl.h" 9 10 #define QUICHE_EXCLUSIVE_LOCKS_REQUIRED QUICHE_EXCLUSIVE_LOCKS_REQUIRED_IMPL 11 #define QUICHE_GUARDED_BY QUICHE_GUARDED_BY_IMPL 12 #define QUICHE_LOCKABLE QUICHE_LOCKABLE_IMPL 13 #define QUICHE_LOCKS_EXCLUDED QUICHE_LOCKS_EXCLUDED_IMPL 14 #define QUICHE_SHARED_LOCKS_REQUIRED QUICHE_SHARED_LOCKS_REQUIRED_IMPL 15 #define QUICHE_EXCLUSIVE_LOCK_FUNCTION QUICHE_EXCLUSIVE_LOCK_FUNCTION_IMPL 16 #define QUICHE_UNLOCK_FUNCTION QUICHE_UNLOCK_FUNCTION_IMPL 17 #define QUICHE_SHARED_LOCK_FUNCTION QUICHE_SHARED_LOCK_FUNCTION_IMPL 18 #define QUICHE_SCOPED_LOCKABLE QUICHE_SCOPED_LOCKABLE_IMPL 19 #define QUICHE_ASSERT_SHARED_LOCK QUICHE_ASSERT_SHARED_LOCK_IMPL 20 21 namespace quiche { 22 23 // A class representing a non-reentrant mutex in QUIC. 24 class QUICHE_LOCKABLE QUICHE_EXPORT QuicheMutex { 25 public: 26 QuicheMutex() = default; 27 QuicheMutex(const QuicheMutex&) = delete; 28 QuicheMutex& operator=(const QuicheMutex&) = delete; 29 30 // Block until this Mutex is free, then acquire it exclusively. 31 void WriterLock() QUICHE_EXCLUSIVE_LOCK_FUNCTION(); 32 33 // Release this Mutex. Caller must hold it exclusively. 34 void WriterUnlock() QUICHE_UNLOCK_FUNCTION(); 35 36 // Block until this Mutex is free or shared, then acquire a share of it. 37 void ReaderLock() QUICHE_SHARED_LOCK_FUNCTION(); 38 39 // Release this Mutex. Caller could hold it in shared mode. 40 void ReaderUnlock() QUICHE_UNLOCK_FUNCTION(); 41 42 // Returns immediately if current thread holds the Mutex in at least shared 43 // mode. Otherwise, may report an error (typically by crashing with a 44 // diagnostic), or may return immediately. 45 void AssertReaderHeld() const QUICHE_ASSERT_SHARED_LOCK(); 46 47 private: 48 QuicheLockImpl impl_; 49 }; 50 51 // A helper class that acquires the given QuicheMutex shared lock while the 52 // QuicheReaderMutexLock is in scope. 53 class QUICHE_SCOPED_LOCKABLE QUICHE_EXPORT QuicheReaderMutexLock { 54 public: 55 explicit QuicheReaderMutexLock(QuicheMutex* lock) 56 QUICHE_SHARED_LOCK_FUNCTION(lock); 57 QuicheReaderMutexLock(const QuicheReaderMutexLock&) = delete; 58 QuicheReaderMutexLock& operator=(const QuicheReaderMutexLock&) = delete; 59 60 ~QuicheReaderMutexLock() QUICHE_UNLOCK_FUNCTION(); 61 62 private: 63 QuicheMutex* const lock_; 64 }; 65 66 // A helper class that acquires the given QuicheMutex exclusive lock while the 67 // QuicheWriterMutexLock is in scope. 68 class QUICHE_SCOPED_LOCKABLE QUICHE_EXPORT QuicheWriterMutexLock { 69 public: 70 explicit QuicheWriterMutexLock(QuicheMutex* lock) 71 QUICHE_EXCLUSIVE_LOCK_FUNCTION(lock); 72 QuicheWriterMutexLock(const QuicheWriterMutexLock&) = delete; 73 QuicheWriterMutexLock& operator=(const QuicheWriterMutexLock&) = delete; 74 75 ~QuicheWriterMutexLock() QUICHE_UNLOCK_FUNCTION(); 76 77 private: 78 QuicheMutex* const lock_; 79 }; 80 81 // A Notification allows threads to receive notification of a single occurrence 82 // of a single event. 83 class QUICHE_EXPORT QuicheNotification { 84 public: 85 QuicheNotification() = default; 86 QuicheNotification(const QuicheNotification&) = delete; 87 QuicheNotification& operator=(const QuicheNotification&) = delete; 88 HasBeenNotified()89 bool HasBeenNotified() { return impl_.HasBeenNotified(); } 90 Notify()91 void Notify() { impl_.Notify(); } 92 WaitForNotification()93 void WaitForNotification() { impl_.WaitForNotification(); } 94 95 private: 96 QuicheNotificationImpl impl_; 97 }; 98 99 } // namespace quiche 100 101 #endif // QUICHE_COMMON_PLATFORM_API_QUICHE_MUTEX_H_ 102