hold strong ref for returned objects (#91)

This commit is contained in:
mihacooper 2017-10-18 10:15:33 +03:00 committed by Ilia
parent 7b73a0e0d9
commit f77391baa5
4 changed files with 32 additions and 2 deletions

View File

@ -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;

View File

@ -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_;

View File

@ -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;

View File

@ -68,4 +68,25 @@ if not os.getenv("APPVEYOR") then
test.equal(chan:pop(10), "hello!") test.equal(chan:pop(10), "hello!")
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