blob: 368515c9e51818ff2e3d2681dc9524ff5398c1f2 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#ifdef __cplusplus
#include <zircon/compiler.h>
#include <fbl/macros.h>
// Notes about class Mutex
//
// Mutex is a C++ helper class intended to wrap a mutex-style synchronization
// primitive and provide a common interface for library code which is intended
// to be shared between user-mode and kernel code. It is also responsible for
// automatically initializing and destroying the internal mutex object.
#if _KERNEL
#include <kernel/mutex.h>
#include <sys/types.h>
namespace fbl {
class __TA_CAPABILITY("mutex") Mutex {
public:
constexpr Mutex() = default;
~Mutex() = default;
void Acquire() __TA_ACQUIRE() { mutex_acquire(&mutex_); }
void Release() __TA_RELEASE() { mutex_release(&mutex_); }
bool IsHeld() const {
return is_mutex_held(&mutex_);
}
mutex_t* GetInternal() __TA_RETURN_CAPABILITY(mutex_) {
return &mutex_;
}
// suppress default constructors
DISALLOW_COPY_ASSIGN_AND_MOVE(Mutex);
private:
mutex_t mutex_;
};
class __TA_CAPABILITY("mutex") NullMutex {
public:
constexpr NullMutex() = default;
void Acquire() __TA_ACQUIRE() { }
void Release() __TA_RELEASE() { }
DISALLOW_COPY_ASSIGN_AND_MOVE(NullMutex);
};
} // namespace fbl
#else // if _KERNEL
#include <zircon/types.h>
#include <threads.h>
namespace fbl {
class __TA_CAPABILITY("mutex") Mutex {
public:
#ifdef MTX_INIT
constexpr Mutex() : mutex_(MTX_INIT) { }
#else
Mutex() { mtx_init(&mutex_, mtx_plain); }
#endif
~Mutex() { mtx_destroy(&mutex_); }
void Acquire() __TA_ACQUIRE() { mtx_lock(&mutex_); }
void Release() __TA_RELEASE() { mtx_unlock(&mutex_); }
/* IsHeld is not supported by the Mutex wrapper in user-mode as C11 mtx_t
* instances do not support a direct IsHeld style check. A possible
* implementation could be built out of mtx_trylock, but would require
* either relaxing away the const constraint on the method signature, or
* flagging the mutex_ member as mutable */
mtx_t* GetInternal() __TA_RETURN_CAPABILITY(mutex_) {
return &mutex_;
}
// suppress default constructors
DISALLOW_COPY_ASSIGN_AND_MOVE(Mutex);
private:
mtx_t mutex_;
};
}
#endif // if _KERNEL
#endif // ifdef __cplusplus