fix synchronization issues

This commit is contained in:
falsycat 2022-09-15 19:36:21 +09:00
parent 8339cc814a
commit c5590092fa
3 changed files with 44 additions and 33 deletions

View File

@ -1,5 +1,6 @@
#pragma once
#include <atomic>
#include <cassert>
#include <memory>
@ -28,7 +29,7 @@ class Life final {
T* const ptr_;
struct Data final {
T* ptr;
std::atomic<T*> ptr;
};
std::shared_ptr<Data> data_;
};

View File

@ -76,13 +76,15 @@ class AudioContext::Queue final : public nf7::audio::Queue,
public std::enable_shared_from_this<AudioContext::Queue> {
public:
struct Runner final {
Runner(Queue& owner) noexcept : owner_(&owner) {
Runner(std::weak_ptr<Queue> owner) noexcept : owner_(owner) {
}
void operator()(Task&& t) {
t(owner_->ctx_.get());
if (auto k = owner_.lock()) {
t(k->ctx_.get());
}
}
private:
Queue* const owner_;
std::weak_ptr<Queue> owner_;
};
using Thread = nf7::Thread<Runner, Task>;
@ -92,9 +94,25 @@ class AudioContext::Queue final : public nf7::audio::Queue,
kBroken,
};
static std::shared_ptr<Queue> Create(AudioContext& f) noexcept {
auto ret = std::make_shared<Queue>(f);
ret->th_ = std::make_shared<Thread>(f, Runner {ret});
ret->Push(
std::make_shared<nf7::GenericContext>(f.env(), 0, "creating ma_context"),
[ret](auto) {
auto ctx = std::make_shared<ma_context>();
if (MA_SUCCESS == ma_context_init(nullptr, 0, nullptr, ctx.get())) {
ret->ctx_ = std::move(ctx);
ret->state_ = kReady;
} else {
ret->state_ = kBroken;
}
});
return ret;
}
Queue() = delete;
Queue(AudioContext& f) noexcept :
env_(&f.env()), th_(std::make_shared<Thread>(f, Runner {*this})) {
Queue(AudioContext& f) noexcept : env_(&f.env()) {
}
~Queue() noexcept {
th_->Push(
@ -107,20 +125,6 @@ class AudioContext::Queue final : public nf7::audio::Queue,
Queue& operator=(const Queue&) = delete;
Queue& operator=(Queue&&) = delete;
void Init() noexcept {
th_->Push(
std::make_shared<nf7::GenericContext>(*env_, 0, "creating ma_context"),
[this, self = shared_from_this()](auto) {
auto ctx = std::make_shared<ma_context>();
if (MA_SUCCESS == ma_context_init(nullptr, 0, nullptr, ctx.get())) {
ctx_ = std::move(ctx);
state_ = kReady;
} else {
state_ = kBroken;
}
});
}
void Push(const std::shared_ptr<nf7::Context>& ctx, Task&& task) noexcept override {
th_->Push(ctx, std::move(task));
}
@ -138,8 +142,7 @@ class AudioContext::Queue final : public nf7::audio::Queue,
};
AudioContext::AudioContext(Env& env) noexcept :
File(kType, env), DirItem(DirItem::kMenu | DirItem::kTooltip),
q_(std::make_shared<Queue>(*this)) {
q_->Init();
q_(AudioContext::Queue::Create(*this)) {
}

View File

@ -33,11 +33,7 @@ class LuaContext final : public nf7::File, public nf7::DirItem {
class Queue;
LuaContext(nf7::Env& env) :
nf7::File(kType, env),
nf7::DirItem(nf7::DirItem::kMenu | nf7::DirItem::kTooltip) {
q_ = std::make_shared<Queue>(*this);
}
LuaContext(nf7::Env& env);
LuaContext(nf7::Deserializer& ar) : LuaContext(ar.env()) {
}
@ -63,20 +59,26 @@ class LuaContext::Queue final : public nf7::luajit::Queue,
public std::enable_shared_from_this<LuaContext::Queue> {
public:
struct Runner final {
Runner(Queue& owner) noexcept : owner_(&owner) {
Runner(std::weak_ptr<Queue> owner) noexcept : owner_(owner) {
}
void operator()(Task&& t) {
t(owner_->L);
if (auto k = owner_.lock()) {
t(k->L);
}
}
private:
Queue* const owner_;
std::weak_ptr<Queue> owner_;
};
using Thread = nf7::Thread<Runner, Task>;
static std::shared_ptr<Queue> Create(LuaContext& f) {
auto ret = std::make_shared<Queue>(f);
ret->th_ = std::make_shared<Thread>(f, Runner {ret});
return ret;
}
Queue() = delete;
Queue(LuaContext& f) :
L(luaL_newstate()), env_(&f.env()),
th_(std::make_shared<Thread>(f, Runner {*this})) {
Queue(LuaContext& f) : L(luaL_newstate()), env_(&f.env()) {
if (!L) throw nf7::Exception("failed to create new Lua state");
}
~Queue() noexcept {
@ -102,6 +104,11 @@ class LuaContext::Queue final : public nf7::luajit::Queue,
Env* const env_;
std::shared_ptr<Thread> th_;
};
LuaContext::LuaContext(nf7::Env& env) :
nf7::File(kType, env),
nf7::DirItem(nf7::DirItem::kMenu | nf7::DirItem::kTooltip),
q_(Queue::Create(*this)) {
}
void LuaContext::UpdateMenu() noexcept {