fix context leak by yielding LuaJIT thread
This commit is contained in:
parent
5b566acd10
commit
de0f2a4a8a
@ -390,7 +390,7 @@ void PushNodeRootLambda(
|
||||
}).template Catch<nf7::Exception>(nullptr, [L, th](nf7::Exception&) {
|
||||
th->ExecResume(L);
|
||||
});
|
||||
return th->Yield(L);
|
||||
return th->Yield(L, la);
|
||||
}
|
||||
});
|
||||
lua_setfield(L, -2, "recv");
|
||||
|
@ -48,12 +48,15 @@ void Thread::Resume(lua_State* L, int narg) noexcept {
|
||||
lua_setfield(L, -2, "nf7");
|
||||
lua_pop(L, 1);
|
||||
|
||||
state_ = kRunning;
|
||||
k.unlock();
|
||||
state_ = kRunning;
|
||||
active_ = true;
|
||||
yield_ctx_.reset();
|
||||
|
||||
k.unlock();
|
||||
const auto ret = lua_resume(L, narg);
|
||||
active_ = false;
|
||||
k.lock();
|
||||
|
||||
active_ = false;
|
||||
if (state_ == kAborted) return;
|
||||
switch (ret) {
|
||||
case 0:
|
||||
@ -67,13 +70,24 @@ void Thread::Resume(lua_State* L, int narg) noexcept {
|
||||
th_ref_ = std::nullopt;
|
||||
state_ = kAborted;
|
||||
}
|
||||
if (!std::exchange(skip_handle_, false)) {
|
||||
if (!std::exchange(skip_handler_, false)) {
|
||||
k.unlock();
|
||||
handler_(*this, L);
|
||||
}
|
||||
}
|
||||
void Thread::Abort() noexcept {
|
||||
std::unique_lock<std::mutex> k(mtx_);
|
||||
state_ = kAborted;
|
||||
state_ = kAborted;
|
||||
th_ref_ = std::nullopt;
|
||||
|
||||
auto wctx = std::move(yield_ctx_);
|
||||
yield_ctx_.reset();
|
||||
k.unlock();
|
||||
if (auto ctx = wctx.lock()) {
|
||||
if (ctx.get() != this) {
|
||||
ctx->Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,8 +97,9 @@ class Thread final : public nf7::Context,
|
||||
|
||||
// must be called on luajit thread
|
||||
// handler_ won't be called on this yielding
|
||||
int Yield(lua_State* L) {
|
||||
skip_handle_ = true;
|
||||
int Yield(lua_State* L, const std::shared_ptr<nf7::Context>& ctx = nullptr) {
|
||||
yield_ctx_ = ctx;
|
||||
skip_handler_ = true;
|
||||
return lua_yield(L, 0);
|
||||
}
|
||||
|
||||
@ -153,8 +154,9 @@ class Thread final : public nf7::Context,
|
||||
|
||||
|
||||
// mutable params
|
||||
bool active_ = false; // true while executing lua_resume
|
||||
bool skip_handle_ = false; // handler_ won't be called on next yield
|
||||
bool active_ = false; // true while executing lua_resume
|
||||
bool skip_handler_ = false;
|
||||
std::weak_ptr<nf7::Context> yield_ctx_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -77,6 +77,7 @@ class NodeRootLambda : public nf7::Node::Lambda,
|
||||
|
||||
void Abort() noexcept override {
|
||||
target_->Abort();
|
||||
pro_ = std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
x
Reference in New Issue
Block a user