hold strong ref for returned objects (#91)
This commit is contained in:
parent
7b73a0e0d9
commit
f77391baa5
@ -63,8 +63,10 @@ StoredArray Channel::pop(const sol::optional<int>& duration,
|
||||
}
|
||||
|
||||
auto ret = data_->channel_.front();
|
||||
for (const auto& obj: ret)
|
||||
for (const auto& obj: ret) {
|
||||
obj->holdStrongReference();
|
||||
removeReference(obj->gcHandle());
|
||||
}
|
||||
|
||||
data_->channel_.pop();
|
||||
return ret;
|
||||
|
||||
@ -97,6 +97,12 @@ public:
|
||||
strongRef_ = sol::nullopt;
|
||||
}
|
||||
|
||||
void holdStrongReference() override {
|
||||
if (!strongRef_) {
|
||||
strongRef_ = GC::instance().get<T>(handle_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GCObjectHandle handle_;
|
||||
sol::optional<T> strongRef_;
|
||||
|
||||
@ -24,6 +24,7 @@ public:
|
||||
virtual sol::object unpack(sol::this_state state) const = 0;
|
||||
virtual GCObjectHandle gcHandle() const { return GCNull; }
|
||||
virtual void releaseStrongReference() { }
|
||||
virtual void holdStrongReference() { }
|
||||
|
||||
private:
|
||||
BaseHolder(const BaseHolder&) = delete;
|
||||
|
||||
@ -69,3 +69,24 @@ if not os.getenv("APPVEYOR") then
|
||||
test.is_true(os.time() < start_time + 10)
|
||||
end
|
||||
end
|
||||
|
||||
-- regress for channel returns
|
||||
test.channel_stress.retun_tables = function ()
|
||||
local function worker()
|
||||
local effil = require "effil"
|
||||
local ch = effil.channel()
|
||||
for i = 1, 1000 do
|
||||
ch:push(effil.table())
|
||||
local ret = { ch:pop() }
|
||||
end
|
||||
end
|
||||
|
||||
local threads = {}
|
||||
|
||||
for i = 1, 20 do
|
||||
table.insert(threads, effil.thread(worker)())
|
||||
end
|
||||
for _, thr in ipairs(threads) do
|
||||
thr:wait()
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user