mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-29 14:32:58 +02:00
util::unique_lock, update loader to new sf semantics
This commit is contained in:
parent
a1504c0df4
commit
0b2c4bb70e
@ -42,9 +42,9 @@ namespace ams::fssrv::impl {
|
|||||||
private:
|
private:
|
||||||
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
||||||
std::unique_ptr<fs::fsa::IFile> base_file;
|
std::unique_ptr<fs::fsa::IFile> base_file;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
public:
|
public:
|
||||||
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||||
~FileInterfaceAdapter();
|
~FileInterfaceAdapter();
|
||||||
private:
|
private:
|
||||||
void InvalidateCache();
|
void InvalidateCache();
|
||||||
@ -64,9 +64,9 @@ namespace ams::fssrv::impl {
|
|||||||
private:
|
private:
|
||||||
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
||||||
std::unique_ptr<fs::fsa::IDirectory> base_dir;
|
std::unique_ptr<fs::fsa::IDirectory> base_dir;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
public:
|
public:
|
||||||
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||||
~DirectoryInterfaceAdapter();
|
~DirectoryInterfaceAdapter();
|
||||||
public:
|
public:
|
||||||
/* Command API */
|
/* Command API */
|
||||||
@ -79,7 +79,7 @@ namespace ams::fssrv::impl {
|
|||||||
NON_COPYABLE(FileSystemInterfaceAdapter);
|
NON_COPYABLE(FileSystemInterfaceAdapter);
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
|
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
|
||||||
os::ReadWriteLock invalidation_lock;
|
os::ReadWriteLock invalidation_lock;
|
||||||
bool open_count_limited;
|
bool open_count_limited;
|
||||||
bool deep_retry_enabled = false;
|
bool deep_retry_enabled = false;
|
||||||
|
@ -32,7 +32,7 @@ namespace ams::fssrv::impl {
|
|||||||
private:
|
private:
|
||||||
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
|
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
|
||||||
std::shared_ptr<fs::IStorage> base_storage;
|
std::shared_ptr<fs::IStorage> base_storage;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
os::ReadWriteLock invalidation_lock;
|
os::ReadWriteLock invalidation_lock;
|
||||||
/* TODO: DataStorageContext. */
|
/* TODO: DataStorageContext. */
|
||||||
bool deep_retry_enabled = false;
|
bool deep_retry_enabled = false;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
||||||
: parent_filesystem(parent, true), base_file(std::move(file)), open_count_semaphore(std::move(sema))
|
: parent_filesystem(parent, true), base_file(std::move(file)), open_count_semaphore(std::move(sema))
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
@ -89,7 +89,7 @@ namespace ams::fssrv::impl {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
||||||
: parent_filesystem(parent, true), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
|
: parent_filesystem(parent, true), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
@ -236,7 +236,7 @@ namespace ams::fssrv::impl {
|
|||||||
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
|
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
|
||||||
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
||||||
|
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
if (this->open_count_limited) {
|
if (this->open_count_limited) {
|
||||||
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
||||||
AMS_ABORT_UNLESS(false);
|
AMS_ABORT_UNLESS(false);
|
||||||
@ -264,7 +264,7 @@ namespace ams::fssrv::impl {
|
|||||||
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
|
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
|
||||||
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
||||||
|
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
if (this->open_count_limited) {
|
if (this->open_count_limited) {
|
||||||
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
||||||
AMS_ABORT_UNLESS(false);
|
AMS_ABORT_UNLESS(false);
|
||||||
|
@ -22,10 +22,10 @@ namespace ams::fssystem {
|
|||||||
NON_COPYABLE(KeySlotCacheAccessor);
|
NON_COPYABLE(KeySlotCacheAccessor);
|
||||||
NON_MOVEABLE(KeySlotCacheAccessor);
|
NON_MOVEABLE(KeySlotCacheAccessor);
|
||||||
private:
|
private:
|
||||||
std::unique_lock<os::Mutex> lk;
|
util::unique_lock<os::Mutex> lk;
|
||||||
const s32 slot_index;
|
const s32 slot_index;
|
||||||
public:
|
public:
|
||||||
KeySlotCacheAccessor(s32 idx, std::unique_lock<os::Mutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ }
|
KeySlotCacheAccessor(s32 idx, util::unique_lock<os::Mutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ }
|
||||||
|
|
||||||
s32 GetKeySlotIndex() const { return this->slot_index; }
|
s32 GetKeySlotIndex() const { return this->slot_index; }
|
||||||
};
|
};
|
||||||
@ -79,7 +79,7 @@ namespace ams::fssystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result Find(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) {
|
Result Find(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
|
|
||||||
KeySlotCacheEntryList *lists[2] = { std::addressof(this->high_priority_mru_list), std::addressof(this->low_priority_mru_list) };
|
KeySlotCacheEntryList *lists[2] = { std::addressof(this->high_priority_mru_list), std::addressof(this->low_priority_mru_list) };
|
||||||
for (auto list : lists) {
|
for (auto list : lists) {
|
||||||
@ -100,12 +100,12 @@ namespace ams::fssystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddEntry(KeySlotCacheEntry *entry) {
|
void AddEntry(KeySlotCacheEntry *entry) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
this->low_priority_mru_list.push_front(*entry);
|
this->low_priority_mru_list.push_front(*entry);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result AllocateFromLru(std::unique_ptr<KeySlotCacheAccessor> *out, KeySlotCacheEntryList &dst_list, const void *key, size_t key_size, s32 key2) {
|
Result AllocateFromLru(std::unique_ptr<KeySlotCacheAccessor> *out, KeySlotCacheEntryList &dst_list, const void *key, size_t key_size, s32 key2) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
|
|
||||||
KeySlotCacheEntryList &src_list = this->low_priority_mru_list.empty() ? this->high_priority_mru_list : this->low_priority_mru_list;
|
KeySlotCacheEntryList &src_list = this->low_priority_mru_list.empty() ? this->high_priority_mru_list : this->low_priority_mru_list;
|
||||||
AMS_ASSERT(!src_list.empty());
|
AMS_ASSERT(!src_list.empty());
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <vapours/util/util_overlap.hpp>
|
#include <vapours/util/util_overlap.hpp>
|
||||||
#include <vapours/util/util_string_util.hpp>
|
#include <vapours/util/util_string_util.hpp>
|
||||||
#include <vapours/util/util_string_view.hpp>
|
#include <vapours/util/util_string_view.hpp>
|
||||||
|
#include <vapours/util/util_mutex_utils.hpp>
|
||||||
#include <vapours/util/util_variadic.hpp>
|
#include <vapours/util/util_variadic.hpp>
|
||||||
#include <vapours/util/util_character_encoding.hpp>
|
#include <vapours/util/util_character_encoding.hpp>
|
||||||
#include <vapours/util/util_format_string.hpp>
|
#include <vapours/util/util_format_string.hpp>
|
||||||
|
141
libvapours/include/vapours/util/util_mutex_utils.hpp
Normal file
141
libvapours/include/vapours/util/util_mutex_utils.hpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vapours/common.hpp>
|
||||||
|
#include <vapours/assert.hpp>
|
||||||
|
|
||||||
|
namespace ams::util {
|
||||||
|
|
||||||
|
template<typename _Mutex>
|
||||||
|
class unique_lock {
|
||||||
|
NON_COPYABLE(unique_lock);
|
||||||
|
public:
|
||||||
|
using mutex_type = _Mutex;
|
||||||
|
private:
|
||||||
|
mutex_type *m_mutex;
|
||||||
|
bool m_owns;
|
||||||
|
public:
|
||||||
|
unique_lock() noexcept : m_mutex(nullptr), m_owns(false) { /* ... */ }
|
||||||
|
|
||||||
|
explicit unique_lock(mutex_type &m) noexcept : m_mutex(std::addressof(m)), m_owns(false) {
|
||||||
|
this->lock();
|
||||||
|
m_owns = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(mutex_type &m, std::defer_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(false) { /* ... */ }
|
||||||
|
unique_lock(mutex_type &m, std::try_to_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock()) { /* ... */ }
|
||||||
|
unique_lock(mutex_type &m, std::adopt_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(true) { /* ... */ }
|
||||||
|
|
||||||
|
template<typename _Clock, typename _Duration>
|
||||||
|
unique_lock(mutex_type &m, const std::chrono::time_point<_Clock, _Duration> &time) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock_until(time)) { /* ... */ }
|
||||||
|
|
||||||
|
template<typename _Rep, typename _Period>
|
||||||
|
unique_lock(mutex_type &m, const std::chrono::duration<_Rep, _Period> &time) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock_for(time)) { /* ... */ }
|
||||||
|
|
||||||
|
~unique_lock() noexcept {
|
||||||
|
if (m_owns) {
|
||||||
|
this->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(unique_lock &&rhs) noexcept : m_mutex(rhs.m_mutex), m_owns(rhs.m_owns) {
|
||||||
|
rhs.m_mutex = nullptr;
|
||||||
|
rhs.m_owns = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock &operator=(unique_lock &&rhs) noexcept {
|
||||||
|
if (m_owns) {
|
||||||
|
this->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(std::move(rhs)).swap(*this);
|
||||||
|
|
||||||
|
rhs.m_mutex = nullptr;
|
||||||
|
rhs.m_owns = false;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
|
||||||
|
m_mutex->lock();
|
||||||
|
m_owns = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_lock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
|
||||||
|
m_owns = m_mutex->try_lock();
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Clock, typename _Duration>
|
||||||
|
bool try_lock_until(const std::chrono::time_point<_Clock, _Duration> &time) noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
m_owns = m_mutex->try_lock_until(time);
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Rep, typename _Period>
|
||||||
|
bool try_lock_for(const std::chrono::duration<_Rep, _Period> &time) noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
m_owns = m_mutex->try_lock_for(time);
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void unlock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_owns);
|
||||||
|
if (m_mutex) {
|
||||||
|
m_mutex->unlock();
|
||||||
|
m_owns = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_lock &rhs) noexcept {
|
||||||
|
std::swap(m_mutex, rhs.m_mutex);
|
||||||
|
std::swap(m_owns, rhs.m_owns);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_type *release() noexcept {
|
||||||
|
mutex_type *ret = m_mutex;
|
||||||
|
m_mutex = nullptr;
|
||||||
|
m_owns = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool owns_lock() const noexcept {
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept {
|
||||||
|
return this->owns_lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_type *mutex() const noexcept {
|
||||||
|
return m_mutex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _Mutex>
|
||||||
|
inline void swap(unique_lock<_Mutex> &lhs, unique_lock<_Mutex> &rhs) noexcept { return lhs.swap(rhs); }
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user