RWLock_posix.cpp (2286B)
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/. */ 6 7 #ifdef XP_WIN 8 # error This file should only be compiled on non-Windows platforms. 9 #endif 10 11 #include "mozilla/PlatformRWLock.h" 12 13 #include "mozilla/Assertions.h" 14 15 #include <errno.h> 16 17 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) 18 mozilla::detail::RWLockImpl::RWLockImpl() { 19 MOZ_RELEASE_ASSERT(pthread_rwlock_init(&mRWLock, nullptr) == 0, 20 "pthread_rwlock_init failed"); 21 } 22 23 mozilla::detail::RWLockImpl::~RWLockImpl() { 24 MOZ_RELEASE_ASSERT(pthread_rwlock_destroy(&mRWLock) == 0, 25 "pthread_rwlock_destroy failed"); 26 } 27 28 bool mozilla::detail::RWLockImpl::tryReadLock() { 29 int rv = pthread_rwlock_tryrdlock(&mRWLock); 30 // We allow EDEADLK here because it has been observed returned on macos when 31 // the write lock is held by the current thread. 32 MOZ_RELEASE_ASSERT(rv == 0 || rv == EBUSY || rv == EDEADLK, 33 "pthread_rwlock_tryrdlock failed"); 34 return rv == 0; 35 } 36 37 void mozilla::detail::RWLockImpl::readLock() { 38 MOZ_RELEASE_ASSERT(pthread_rwlock_rdlock(&mRWLock) == 0, 39 "pthread_rwlock_rdlock failed"); 40 } 41 42 void mozilla::detail::RWLockImpl::readUnlock() { 43 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(&mRWLock) == 0, 44 "pthread_rwlock_unlock failed"); 45 } 46 47 bool mozilla::detail::RWLockImpl::tryWriteLock() { 48 int rv = pthread_rwlock_trywrlock(&mRWLock); 49 // We allow EDEADLK here because it has been observed returned on macos when 50 // the write lock is held by the current thread. 51 MOZ_RELEASE_ASSERT(rv == 0 || rv == EBUSY || rv == EDEADLK, 52 "pthread_rwlock_trywrlock failed"); 53 return rv == 0; 54 } 55 56 void mozilla::detail::RWLockImpl::writeLock() { 57 MOZ_RELEASE_ASSERT(pthread_rwlock_wrlock(&mRWLock) == 0, 58 "pthread_rwlock_wrlock failed"); 59 } 60 61 void mozilla::detail::RWLockImpl::writeUnlock() { 62 MOZ_RELEASE_ASSERT(pthread_rwlock_unlock(&mRWLock) == 0, 63 "pthread_rwlock_unlock failed"); 64 }