Bug 1755481: correct documentation of `nsIClipboard::getData`. r=mccr8
[gecko.git] / xpcom / threads / RWLock.cpp
blob56f5522983932227c18ee1d70b569c95da8b24d2
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"
9 #ifdef XP_WIN
10 # include <windows.h>
12 static_assert(sizeof(SRWLOCK) <= sizeof(void*), "SRWLOCK is too big!");
14 # define NativeHandle(m) (reinterpret_cast<SRWLOCK*>(&m))
15 #else
16 # define NativeHandle(m) (&m)
17 #endif
19 namespace mozilla {
21 RWLock::RWLock(const char* aName)
22 : BlockingResourceBase(aName, eMutex)
23 #ifdef DEBUG
25 mOwningThread(nullptr)
26 #endif
28 #ifdef XP_WIN
29 InitializeSRWLock(NativeHandle(mRWLock));
30 #else
31 MOZ_RELEASE_ASSERT(pthread_rwlock_init(NativeHandle(mRWLock), nullptr) == 0,
32 "pthread_rwlock_init failed");
33 #endif
36 #ifdef DEBUG
37 bool RWLock::LockedForWritingByCurrentThread() {
38 return mOwningThread == PR_GetCurrentThread();
40 #endif
42 #ifndef XP_WIN
43 RWLock::~RWLock() {
44 MOZ_RELEASE_ASSERT(pthread_rwlock_destroy(NativeHandle(mRWLock)) == 0,
45 "pthread_rwlock_destroy failed");
47 #endif
49 bool RWLock::TryReadLockInternal() {
50 #ifdef XP_WIN
51 return TryAcquireSRWLockShared(NativeHandle(mRWLock));
52 #else
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");
58 return rv == 0;
59 #endif
62 void RWLock::ReadLockInternal() {
63 #ifdef XP_WIN
64 AcquireSRWLockShared(NativeHandle(mRWLock));
65 #else
66 MOZ_RELEASE_ASSERT(pthread_rwlock_rdlock(NativeHandle(mRWLock)) == 0,
67 "pthread_rwlock_rdlock failed");
68 #endif
71 void RWLock::ReadUnlockInternal() {
72 #ifdef XP_WIN
73 ReleaseSRWLockShared(NativeHandle(mRWLock));
74 #else
75 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(NativeHandle(mRWLock)) == 0,
76 "pthread_rwlock_unlock failed");
77 #endif
80 bool RWLock::TryWriteLockInternal() {
81 #ifdef XP_WIN
82 return TryAcquireSRWLockExclusive(NativeHandle(mRWLock));
83 #else
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");
89 return rv == 0;
90 #endif
93 void RWLock::WriteLockInternal() {
94 #ifdef XP_WIN
95 AcquireSRWLockExclusive(NativeHandle(mRWLock));
96 #else
97 MOZ_RELEASE_ASSERT(pthread_rwlock_wrlock(NativeHandle(mRWLock)) == 0,
98 "pthread_rwlock_wrlock failed");
99 #endif
102 void RWLock::WriteUnlockInternal() {
103 #ifdef XP_WIN
104 ReleaseSRWLockExclusive(NativeHandle(mRWLock));
105 #else
106 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(NativeHandle(mRWLock)) == 0,
107 "pthread_rwlock_unlock failed");
108 #endif
111 } // namespace mozilla
113 #undef NativeHandle