1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/RWLock.h"
12 static_assert(sizeof(SRWLOCK
) <= sizeof(void*), "SRWLOCK is too big!");
14 # define NativeHandle(m) (reinterpret_cast<SRWLOCK*>(&m))
16 # define NativeHandle(m) (&m)
21 RWLock::RWLock(const char* aName
)
22 : BlockingResourceBase(aName
, eMutex
)
25 mOwningThread(nullptr)
29 InitializeSRWLock(NativeHandle(mRWLock
));
31 MOZ_RELEASE_ASSERT(pthread_rwlock_init(NativeHandle(mRWLock
), nullptr) == 0,
32 "pthread_rwlock_init failed");
37 bool RWLock::LockedForWritingByCurrentThread() {
38 return mOwningThread
== PR_GetCurrentThread();
44 MOZ_RELEASE_ASSERT(pthread_rwlock_destroy(NativeHandle(mRWLock
)) == 0,
45 "pthread_rwlock_destroy failed");
49 bool RWLock::TryReadLockInternal() {
51 return TryAcquireSRWLockShared(NativeHandle(mRWLock
));
53 int rv
= pthread_rwlock_tryrdlock(NativeHandle(mRWLock
));
54 // We allow EDEADLK here because it has been observed returned on macos when
55 // the write lock is held by the current thread.
56 MOZ_RELEASE_ASSERT(rv
== 0 || rv
== EBUSY
|| rv
== EDEADLK
,
57 "pthread_rwlock_tryrdlock failed");
62 void RWLock::ReadLockInternal() {
64 AcquireSRWLockShared(NativeHandle(mRWLock
));
66 MOZ_RELEASE_ASSERT(pthread_rwlock_rdlock(NativeHandle(mRWLock
)) == 0,
67 "pthread_rwlock_rdlock failed");
71 void RWLock::ReadUnlockInternal() {
73 ReleaseSRWLockShared(NativeHandle(mRWLock
));
75 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(NativeHandle(mRWLock
)) == 0,
76 "pthread_rwlock_unlock failed");
80 bool RWLock::TryWriteLockInternal() {
82 return TryAcquireSRWLockExclusive(NativeHandle(mRWLock
));
84 int rv
= pthread_rwlock_trywrlock(NativeHandle(mRWLock
));
85 // We allow EDEADLK here because it has been observed returned on macos when
86 // the write lock is held by the current thread.
87 MOZ_RELEASE_ASSERT(rv
== 0 || rv
== EBUSY
|| rv
== EDEADLK
,
88 "pthread_rwlock_trywrlock failed");
93 void RWLock::WriteLockInternal() {
95 AcquireSRWLockExclusive(NativeHandle(mRWLock
));
97 MOZ_RELEASE_ASSERT(pthread_rwlock_wrlock(NativeHandle(mRWLock
)) == 0,
98 "pthread_rwlock_wrlock failed");
102 void RWLock::WriteUnlockInternal() {
104 ReleaseSRWLockExclusive(NativeHandle(mRWLock
));
106 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(NativeHandle(mRWLock
)) == 0,
107 "pthread_rwlock_unlock failed");
111 } // namespace mozilla