80 lines
1.7 KiB
C++
80 lines
1.7 KiB
C++
#pragma once
|
|
#ifndef _NB_CORE_TYPES
|
|
#define _NB_CORE_TYPES
|
|
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include "Errors.hpp"
|
|
|
|
namespace nb {
|
|
|
|
using ByteVector = std::vector<uint8_t>;
|
|
|
|
class ObjectManagerError : public Error<ObjectManagerError> {
|
|
using Base = Error<ObjectManagerError>;
|
|
|
|
public:
|
|
using Base::Base;
|
|
|
|
enum Codes : unsigned int {
|
|
UNDEFINED, NO_MANAGER, MANAGER_MISMATCH, LOCK_OVERFLOW, BAD_THREAD
|
|
};
|
|
|
|
static const std::string type;
|
|
static const ErrorCodeMap ErrorMessages;
|
|
};
|
|
|
|
template <typename T>
|
|
class ThreadsafeObjectLock;
|
|
|
|
template <typename T>
|
|
class ThreadsafeObject {
|
|
using Codes = ObjectManagerError::Codes;
|
|
|
|
public:
|
|
ThreadsafeObject(T&& obj)
|
|
: _obj(std::make_shared<T>(obj)) {}
|
|
|
|
ThreadsafeObjectLock<T> lock() {
|
|
return ThreadsafeObjectLock<T>(this);
|
|
}
|
|
|
|
friend ThreadsafeObjectLock<T>;
|
|
|
|
protected:
|
|
std::shared_ptr<T> _obj;
|
|
mutable std::recursive_mutex _mutex;
|
|
|
|
};
|
|
|
|
template <typename T>
|
|
class ThreadsafeObjectLock {
|
|
public:
|
|
ThreadsafeObjectLock(const ThreadsafeObjectLock&) = delete;
|
|
ThreadsafeObjectLock operator=(const ThreadsafeObjectLock&) = delete;
|
|
~ThreadsafeObjectLock() {
|
|
_manager->_mutex.unlock();
|
|
}
|
|
|
|
T* operator->() {
|
|
return _manager->_obj.get();
|
|
}
|
|
|
|
friend ThreadsafeObject<T>;
|
|
|
|
protected:
|
|
ThreadsafeObjectLock(
|
|
ThreadsafeObject<T>* const manager_
|
|
) : _manager(manager_) {
|
|
if (!_manager) {
|
|
using Codes = ObjectManagerError::Codes;
|
|
THROW(ObjectManagerError(Codes::NO_MANAGER));
|
|
}
|
|
_manager->_mutex.lock();
|
|
}
|
|
ThreadsafeObject<T>* const _manager;
|
|
};
|
|
|
|
} // namespace nb
|
|
#endif // _NB_CORE_TYPES
|