1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-08 13:11:49 +00:00

meso: Implement KObjectRegistry

This commit is contained in:
TuxSH 2018-11-13 16:06:20 +01:00 committed by Michael Scire
parent fb4e0988b9
commit 757aa30e74
3 changed files with 134 additions and 0 deletions

View file

@ -389,6 +389,18 @@ class KLinkedList final {
return nd->data;
}
template< class... Args>
T *emplace_back_or_fail(Args&&... args)
{
auto *nd = new typename List::Node{std::forward<Args>(args)...};
if (nd != nullptr) {
insert_node_after(list.last(), &nd->link);
return &nd->data;
} else {
return nullptr;
}
}
void pop_back()
{
auto *nd = list.last();

View file

@ -0,0 +1,43 @@
#pragma once
#include <mesosphere/core/KAutoObject.hpp>
#include <mesosphere/core/KLinkedList.hpp>
#include <mesosphere/core/Result.hpp>
#include <mesosphere/threading/KMutex.hpp>
#include <cstring>
namespace mesosphere
{
class KObjectRegistry {
public:
static KObjectRegistry &GetInstance() { return instance; }
SharedPtr<KAutoObject> Find(const char *name) const;
Result Register(SharedPtr<KAutoObject> obj, const char *name);
Result Unregister(const char *name);
private:
struct Node {
SharedPtr<KAutoObject> obj{};
char name[12] = {0};
Node() = default;
Node(SharedPtr<KAutoObject> &&obj, const char *name) : obj{obj}
{
std::strncpy(this->name, name, sizeof(this->name));
}
};
const Node *FindImpl(const char *name) const;
Node *FindImpl(const char *name);
KLinkedList<Node> nameNodes{};
mutable KMutex mutex{};
static KObjectRegistry instance;
};
}

View file

@ -0,0 +1,79 @@
#include <mesosphere/core/KObjectRegistry.hpp>
#include <utility>
namespace mesosphere
{
KObjectRegistry KObjectRegistry::instance{};
const KObjectRegistry::Node *KObjectRegistry::FindImpl(const char *name) const
{
auto it = std::find_if(
nameNodes.cbegin(),
nameNodes.cend(),
[name](const Node &nd) {
return std::strncmp(name, nd.name, sizeof(nd.name)) == 0;
}
);
return it == nameNodes.cend() ? nullptr : &*it;
}
KObjectRegistry::Node *KObjectRegistry::FindImpl(const char *name)
{
auto it = std::find_if(
nameNodes.begin(),
nameNodes.end(),
[name](const Node &nd) {
return std::strncmp(name, nd.name, sizeof(nd.name)) == 0;
}
);
return it == nameNodes.end() ? nullptr : &*it;
}
SharedPtr<KAutoObject> KObjectRegistry::Find(const char *name) const
{
std::scoped_lock guard{mutex};
const Node *node = FindImpl(name);
return node == nullptr ? nullptr : node->obj;
}
Result KObjectRegistry::Register(SharedPtr<KAutoObject> obj, const char *name)
{
std::scoped_lock guard{mutex};
Node *node = FindImpl(name);
if (node != nullptr) {
// Name already exists, just replace the auto object.
node->obj = std::move(obj);
return ResultSuccess();
} else {
if (nameNodes.emplace_back_or_fail(std::move(obj), name) == nullptr) {
return ResultKernelInvalidState();
}
return ResultSuccess();
}
}
Result KObjectRegistry::Unregister(const char *name)
{
std::scoped_lock guard{mutex};
auto it = std::find_if(
nameNodes.cbegin(),
nameNodes.cend(),
[name](const Node &nd) {
return std::strncmp(name, nd.name, sizeof(nd.name)) == 0;
}
);
if (it == nameNodes.cend()) {
return ResultKernelNotFound();
} else {
nameNodes.erase(it);
return ResultSuccess();
}
}
}