add Node/Mutex
This commit is contained in:
parent
7f6fd26c71
commit
e7d37b0adb
@ -146,6 +146,7 @@ target_sources(nf7
|
||||
file/luajit_context.cc
|
||||
file/luajit_node.cc
|
||||
file/node_imm.cc
|
||||
file/node_mutex.cc
|
||||
file/node_network.cc
|
||||
file/node_ref.cc
|
||||
file/node_singleton.cc
|
||||
|
@ -42,6 +42,13 @@ class Mutex final {
|
||||
return k;
|
||||
}
|
||||
|
||||
const char* status() const noexcept {
|
||||
return sync_.expired()? "free": ex_? "exlocked": "locked";
|
||||
}
|
||||
size_t pendings() const noexcept {
|
||||
return pends_.size();
|
||||
}
|
||||
|
||||
std::function<void()> onLock = [](){};
|
||||
std::function<void()> onUnlock = [](){};
|
||||
|
||||
|
111
file/node_mutex.cc
Normal file
111
file/node_mutex.cc
Normal file
@ -0,0 +1,111 @@
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
#include "nf7.hh"
|
||||
|
||||
#include "common/dir_item.hh"
|
||||
#include "common/generic_context.hh"
|
||||
#include "common/generic_type_info.hh"
|
||||
#include "common/life.hh"
|
||||
#include "common/mutex.hh"
|
||||
#include "common/node.hh"
|
||||
#include "common/ptr_selector.hh"
|
||||
|
||||
|
||||
namespace nf7 {
|
||||
|
||||
class MutexNode final : public nf7::File,
|
||||
public nf7::DirItem, public nf7::Node {
|
||||
public:
|
||||
static inline const nf7::GenericTypeInfo<MutexNode> kType = {
|
||||
"Node/Mutex", {"nf7::DirItem",},
|
||||
"mutual exclusion",
|
||||
};
|
||||
|
||||
MutexNode(nf7::Env& env) noexcept :
|
||||
nf7::File(kType, env),
|
||||
nf7::DirItem(nf7::DirItem::kTooltip),
|
||||
nf7::Node(nf7::Node::kNone),
|
||||
life_(*this) {
|
||||
}
|
||||
|
||||
MutexNode(nf7::Deserializer& ar) : MutexNode(ar.env()) {
|
||||
}
|
||||
|
||||
void Serialize(nf7::Serializer&) const noexcept override {}
|
||||
std::unique_ptr<nf7::File> Clone(nf7::Env& env) const noexcept override {
|
||||
return std::make_unique<MutexNode>(env);
|
||||
}
|
||||
|
||||
std::shared_ptr<nf7::Node::Lambda> CreateLambda(
|
||||
const std::shared_ptr<nf7::Node::Lambda>& parent) noexcept override {
|
||||
return std::make_shared<Lambda>(*this, parent);
|
||||
}
|
||||
nf7::Node::Meta GetMeta() const noexcept override {
|
||||
return {{"lock", "exlock", "unlock"}, {"acquired", "failed"}};
|
||||
}
|
||||
|
||||
void UpdateTooltip() noexcept;
|
||||
|
||||
nf7::File::Interface* interface(const std::type_info& t) noexcept override {
|
||||
return nf7::InterfaceSelector<
|
||||
nf7::DirItem, nf7::Node>(t).Select(this);
|
||||
}
|
||||
|
||||
private:
|
||||
nf7::Life<MutexNode> life_;
|
||||
|
||||
nf7::Mutex mtx_;
|
||||
|
||||
class Lambda final : public nf7::Node::Lambda,
|
||||
public std::enable_shared_from_this<Lambda> {
|
||||
public:
|
||||
Lambda(MutexNode& f, const std::shared_ptr<nf7::Node::Lambda>& parent) noexcept :
|
||||
nf7::Node::Lambda(f, parent), f_(f.life_) {
|
||||
}
|
||||
|
||||
void Handle(const nf7::Node::Lambda::Msg& in) noexcept override {
|
||||
if (!f_) return;
|
||||
|
||||
if (in.name == "lock") {
|
||||
Lock(in.sender, false);
|
||||
} else if (in.name == "exlock") {
|
||||
Lock(in.sender, true);
|
||||
} else if (in.name == "unlock") {
|
||||
lock_ = nullptr;
|
||||
}
|
||||
}
|
||||
void Lock(const std::shared_ptr<nf7::Node::Lambda>& sender, bool ex) noexcept {
|
||||
if (lock_ || std::exchange(working_, true)) {
|
||||
return;
|
||||
}
|
||||
auto self = shared_from_this();
|
||||
auto ctx = std::make_shared<nf7::GenericContext>(*f_, "mutex lock", self);
|
||||
f_->mtx_.
|
||||
AcquireLock(ctx, ex).
|
||||
ThenIf([=](auto& k) {
|
||||
self->lock_ = k;
|
||||
self->working_ = false;
|
||||
sender->Handle("acquired", nf7::Value::Pulse {}, self);
|
||||
}).
|
||||
Catch<nf7::Exception>([=](auto&) {
|
||||
self->working_ = false;
|
||||
sender->Handle("failed", nf7::Value::Pulse {}, self);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
nf7::Life<MutexNode>::Ref f_;
|
||||
|
||||
bool working_ = false;
|
||||
std::shared_ptr<nf7::Mutex::Lock> lock_;
|
||||
};
|
||||
};
|
||||
|
||||
void MutexNode::UpdateTooltip() noexcept {
|
||||
ImGui::Text("status : %s", mtx_.status());
|
||||
ImGui::Text("pendings: %zu", mtx_.pendings());
|
||||
}
|
||||
|
||||
} // namespace nf7
|
Loading…
x
Reference in New Issue
Block a user