Fix raise condition in GC objects construction (#154)
* Fix raise condition in GC objects construction * review fixes
This commit is contained in:
parent
5a44ed20c0
commit
b3380a7879
@ -14,11 +14,13 @@ void Channel::exportAPI(sol::state_view& lua) {
|
|||||||
sol::stack::pop<sol::object>(lua);
|
sol::stack::pop<sol::object>(lua);
|
||||||
}
|
}
|
||||||
|
|
||||||
Channel::Channel(const sol::stack_object& capacity) {
|
void Channel::initialize(const sol::stack_object& capacity) {
|
||||||
if (capacity.valid()) {
|
if (capacity.valid()) {
|
||||||
REQUIRE(capacity.get_type() == sol::type::number) << "bad argument #1 to 'effil.channel' (number expected, got "
|
REQUIRE(capacity.get_type() == sol::type::number)
|
||||||
|
<< "bad argument #1 to 'effil.channel' (number expected, got "
|
||||||
<< luaTypename(capacity) << ")";
|
<< luaTypename(capacity) << ")";
|
||||||
REQUIRE(capacity.as<int>() >= 0) << "effil.channel: invalid capacity value = " << capacity.as<int>();
|
REQUIRE(capacity.as<int>() >= 0)
|
||||||
|
<< "effil.channel: invalid capacity value = " << capacity.as<int>();
|
||||||
ctx_->capacity_ = capacity.as<size_t>();
|
ctx_->capacity_ = capacity.as<size_t>();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -27,11 +27,9 @@ public:
|
|||||||
|
|
||||||
size_t size();
|
size_t size();
|
||||||
|
|
||||||
public:
|
|
||||||
Channel() = delete;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Channel(const sol::stack_object& capacity);
|
Channel() = default;
|
||||||
|
void initialize(const sol::stack_object& capacity);
|
||||||
friend class GC;
|
friend class GC;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,16 +2,12 @@
|
|||||||
|
|
||||||
namespace effil {
|
namespace effil {
|
||||||
|
|
||||||
Function::Function(const sol::function& luaObject) {
|
void Function::initialize(const sol::function& luaObject) {
|
||||||
SolTableToShared visited;
|
SolTableToShared visited;
|
||||||
construct(luaObject, visited);
|
initialize(luaObject, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function::Function(const sol::function& luaObject, SolTableToShared& visited) {
|
void Function::initialize(const sol::function& luaObject, SolTableToShared& visited) {
|
||||||
construct(luaObject, visited);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Function::construct(const sol::function& luaObject, SolTableToShared& visited) {
|
|
||||||
assert(luaObject.valid());
|
assert(luaObject.valid());
|
||||||
assert(luaObject.get_type() == sol::type::function);
|
assert(luaObject.get_type() == sol::type::function);
|
||||||
|
|
||||||
|
|||||||
@ -24,10 +24,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
using Converter = std::function<sol::object(const StoredObject&)>;
|
using Converter = std::function<sol::object(const StoredObject&)>;
|
||||||
sol::object convert(lua_State* state, const Converter& clbk) const;
|
sol::object convert(lua_State* state, const Converter& clbk) const;
|
||||||
void construct(const sol::function& luaObject, SolTableToShared& visited);
|
|
||||||
|
|
||||||
explicit Function(const sol::function& luaObject, SolTableToShared& visited);
|
Function() = default;
|
||||||
explicit Function(const sol::function& luaObject);
|
void initialize(const sol::function& luaObject, SolTableToShared& visited);
|
||||||
|
void initialize(const sol::function& luaObject);
|
||||||
friend class GC;
|
friend class GC;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -20,11 +20,15 @@ public:
|
|||||||
if (enabled_ && count() >= step_ * lastCleanup_)
|
if (enabled_ && count() >= step_ * lastCleanup_)
|
||||||
collect();
|
collect();
|
||||||
|
|
||||||
std::unique_ptr<ViewType> object(new ViewType(std::forward<Args>(args)...));
|
std::unique_lock<std::mutex> g(lock_);
|
||||||
|
std::unique_ptr<ViewType> object(new ViewType);
|
||||||
auto copy = *object;
|
auto copy = *object;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
|
||||||
objects_.emplace(object->handle(), std::move(object));
|
objects_.emplace(object->handle(), std::move(object));
|
||||||
|
g.unlock();
|
||||||
|
|
||||||
|
// We separate initialization out of construction cause the object under construction
|
||||||
|
// should be added into GC before it will try to put any other objects into it's references
|
||||||
|
copy.initialize(std::forward<Args>(args)...);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
SharedTable() = default;
|
SharedTable() = default;
|
||||||
|
void initialize() {}
|
||||||
friend class GC;
|
friend class GC;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -179,12 +179,13 @@ void sleep(const sol::stack_object& duration, const sol::stack_object& metric) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(const std::string& path,
|
void Thread::initialize(
|
||||||
|
const std::string& path,
|
||||||
const std::string& cpath,
|
const std::string& cpath,
|
||||||
int step,
|
int step,
|
||||||
const sol::function& function,
|
const sol::function& function,
|
||||||
const sol::variadic_args& variadicArgs) {
|
const sol::variadic_args& variadicArgs)
|
||||||
|
{
|
||||||
sol::optional<Function> functionObj;
|
sol::optional<Function> functionObj;
|
||||||
try {
|
try {
|
||||||
functionObj = GC::instance().create<Function>(function);
|
functionObj = GC::instance().create<Function>(function);
|
||||||
|
|||||||
@ -106,7 +106,9 @@ public:
|
|||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(const std::string& path,
|
Thread() = default;
|
||||||
|
void initialize(
|
||||||
|
const std::string& path,
|
||||||
const std::string& cpath,
|
const std::string& cpath,
|
||||||
int step,
|
int step,
|
||||||
const sol::function& function,
|
const sol::function& function,
|
||||||
|
|||||||
@ -35,3 +35,21 @@ test.gc_stress.create_and_collect_in_parallel = function ()
|
|||||||
test.equal(threads[i]:wait(), "completed")
|
test.equal(threads[i]:wait(), "completed")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test.gc_stress.regress_for_concurent_thread_creation = function ()
|
||||||
|
local a = function() end
|
||||||
|
local b = function() end
|
||||||
|
|
||||||
|
for i = 1, 2000 do
|
||||||
|
effil.thread(function(a, b) a() b() end)(a, b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test.gc_stress.regress_for_concurent_function_creation = function ()
|
||||||
|
local a = function() end
|
||||||
|
local b = function() end
|
||||||
|
|
||||||
|
for i = 1, 2000 do
|
||||||
|
effil.thread(function() a() b() end)()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user