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();
|
auto ret = data_->channel_.front();
|
||||||
for (const auto& obj: ret)
|
for (const auto& obj: ret) {
|
||||||
|
obj->holdStrongReference();
|
||||||
removeReference(obj->gcHandle());
|
removeReference(obj->gcHandle());
|
||||||
|
}
|
||||||
|
|
||||||
data_->channel_.pop();
|
data_->channel_.pop();
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@ -97,6 +97,12 @@ public:
|
|||||||
strongRef_ = sol::nullopt;
|
strongRef_ = sol::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void holdStrongReference() override {
|
||||||
|
if (!strongRef_) {
|
||||||
|
strongRef_ = GC::instance().get<T>(handle_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GCObjectHandle handle_;
|
GCObjectHandle handle_;
|
||||||
sol::optional<T> strongRef_;
|
sol::optional<T> strongRef_;
|
||||||
|
|||||||
@ -24,6 +24,7 @@ public:
|
|||||||
virtual sol::object unpack(sol::this_state state) const = 0;
|
virtual sol::object unpack(sol::this_state state) const = 0;
|
||||||
virtual GCObjectHandle gcHandle() const { return GCNull; }
|
virtual GCObjectHandle gcHandle() const { return GCNull; }
|
||||||
virtual void releaseStrongReference() { }
|
virtual void releaseStrongReference() { }
|
||||||
|
virtual void holdStrongReference() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BaseHolder(const BaseHolder&) = delete;
|
BaseHolder(const BaseHolder&) = delete;
|
||||||
|
|||||||
@ -69,3 +69,24 @@ if not os.getenv("APPVEYOR") then
|
|||||||
test.is_true(os.time() < start_time + 10)
|
test.is_true(os.time() < start_time + 10)
|
||||||
end
|
end
|
||||||
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