blob: e9400d7646f7c9cf4af4171cc2f004f3156ccb54 [file] [log] [blame]
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "starboard/common/mutex.h"
#include "starboard/common/log.h"
namespace starboard {
Mutex::Mutex() : mutex_() {
#if SB_API_VERSION < 16
SbMutexCreate(&mutex_);
#else
pthread_mutex_init(&mutex_, nullptr);
#endif // SB_API_VERSION < 16
debugInit();
}
Mutex::~Mutex() {
#if SB_API_VERSION < 16
SbMutexDestroy(&mutex_);
#else
pthread_mutex_destroy(&mutex_);
#endif // SB_API_VERSION < 16
}
void Mutex::Acquire() const {
debugPreAcquire();
#if SB_API_VERSION < 16
SbMutexAcquire(&mutex_);
#else
pthread_mutex_lock(&mutex_);
#endif // SB_API_VERSION < 16
debugSetAcquired();
}
bool Mutex::AcquireTry() const {
#if SB_API_VERSION < 16
bool ok = SbMutexAcquireTry(&mutex_) == kSbMutexAcquired;
#else
bool ok = pthread_mutex_trylock(&mutex_) == 0;
#endif // SB_API_VERSION < 16
if (ok) {
debugSetAcquired();
}
return ok;
}
void Mutex::Release() const {
debugSetReleased();
#if SB_API_VERSION < 16
SbMutexRelease(&mutex_);
#else
pthread_mutex_unlock(&mutex_);
#endif // SB_API_VERSION < 16
}
void Mutex::DCheckAcquired() const {
#ifdef _DEBUG
SB_DCHECK(pthread_equal(current_thread_acquired_, pthread_self()));
#endif // _DEBUG
}
#ifdef _DEBUG
void Mutex::debugInit() {
current_thread_acquired_ = 0;
}
void Mutex::debugSetReleased() const {
pthread_t current_thread = pthread_self();
SB_DCHECK(pthread_equal(current_thread_acquired_, current_thread));
current_thread_acquired_ = 0;
}
void Mutex::debugPreAcquire() const {
// Check that the mutex is not held by the current thread.
pthread_t current_thread = pthread_self();
SB_DCHECK(!pthread_equal(current_thread_acquired_, current_thread));
}
void Mutex::debugSetAcquired() const {
// Check that the thread has already not been held.
SB_DCHECK(current_thread_acquired_ == 0);
current_thread_acquired_ = pthread_self();
}
#else
void Mutex::debugInit() {}
void Mutex::debugSetReleased() const {}
void Mutex::debugPreAcquire() const {}
void Mutex::debugSetAcquired() const {}
#endif
#if SB_API_VERSION < 16
SbMutex* Mutex::mutex() const {
#else
pthread_mutex_t* Mutex::mutex() const {
#endif
return &mutex_;
}
ScopedLock::ScopedLock(const Mutex& mutex) : mutex_(mutex) {
mutex_.Acquire();
}
ScopedLock::~ScopedLock() {
mutex_.Release();
}
ScopedTryLock::ScopedTryLock(const Mutex& mutex) : mutex_(mutex) {
is_locked_ = mutex_.AcquireTry();
}
ScopedTryLock::~ScopedTryLock() {
if (is_locked_) {
mutex_.Release();
}
}
bool ScopedTryLock::is_locked() const {
return is_locked_;
}
} // namespace starboard