michael@0: /* -*- Mode: C++; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: ** File: btlocks.c michael@0: ** Description: Implemenation for thread locks using bthreads michael@0: ** Exports: prlock.h michael@0: */ michael@0: michael@0: #include "primpl.h" michael@0: michael@0: #include michael@0: #include michael@0: michael@0: void michael@0: _PR_InitLocks (void) michael@0: { michael@0: } michael@0: michael@0: PR_IMPLEMENT(PRLock*) michael@0: PR_NewLock (void) michael@0: { michael@0: PRLock *lock; michael@0: status_t semresult; michael@0: michael@0: if (!_pr_initialized) _PR_ImplicitInitialization(); michael@0: michael@0: lock = PR_NEWZAP(PRLock); michael@0: if (lock != NULL) { michael@0: michael@0: lock->benaphoreCount = 0; michael@0: lock->semaphoreID = create_sem( 0, "nsprLockSem" ); michael@0: if( lock->semaphoreID < B_NO_ERROR ) { michael@0: michael@0: PR_DELETE( lock ); michael@0: lock = NULL; michael@0: } michael@0: } michael@0: michael@0: return lock; michael@0: } michael@0: michael@0: PR_IMPLEMENT(void) michael@0: PR_DestroyLock (PRLock* lock) michael@0: { michael@0: status_t result; michael@0: michael@0: PR_ASSERT(NULL != lock); michael@0: result = delete_sem(lock->semaphoreID); michael@0: PR_ASSERT(result == B_NO_ERROR); michael@0: PR_DELETE(lock); michael@0: } michael@0: michael@0: PR_IMPLEMENT(void) michael@0: PR_Lock (PRLock* lock) michael@0: { michael@0: PR_ASSERT(lock != NULL); michael@0: michael@0: if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) { michael@0: michael@0: if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) { michael@0: michael@0: atomic_add( &lock->benaphoreCount, -1 ); michael@0: return; michael@0: } michael@0: } michael@0: michael@0: lock->owner = find_thread( NULL ); michael@0: } michael@0: michael@0: PR_IMPLEMENT(PRStatus) michael@0: PR_Unlock (PRLock* lock) michael@0: { michael@0: PR_ASSERT(lock != NULL); michael@0: lock->owner = NULL; michael@0: if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) { michael@0: michael@0: release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE ); michael@0: } michael@0: michael@0: return PR_SUCCESS; michael@0: } michael@0: michael@0: PR_IMPLEMENT(void) michael@0: PR_AssertCurrentThreadOwnsLock(PRLock *lock) michael@0: { michael@0: PR_ASSERT(lock != NULL); michael@0: PR_ASSERT(lock->owner == find_thread( NULL )); michael@0: }