Fix codestyle

This commit is contained in:
Ilia Udalov 2017-02-18 14:06:30 +03:00
parent 78f2306657
commit e8bbb5d293
15 changed files with 209 additions and 266 deletions

View File

@ -8,9 +8,9 @@
namespace effil {
GarbageCollector::GarbageCollector()
: state_(GCState::Idle),
lastCleanup_(0),
step_(200) {}
: state_(GCState::Idle)
, lastCleanup_(0)
, step_(200) {}
GCObject* GarbageCollector::get(GCObjectHandle handle) {
std::lock_guard<std::mutex> g(lock_);
@ -32,30 +32,30 @@ bool GarbageCollector::has(GCObjectHandle handle) const {
void GarbageCollector::cleanup() {
std::lock_guard<std::mutex> g(lock_);
if (state_ == GCState::Stopped) return;
if (state_ == GCState::Stopped)
return;
assert(state_ != GCState::Running);
state_ = GCState::Running;
std::vector<GCObjectHandle> grey;
std::map<GCObjectHandle, std::shared_ptr<GCObject>> black;
for(const auto& handleAndObject : objects_)
for (const auto& handleAndObject : objects_)
if (handleAndObject.second->instances() > 1)
grey.push_back(handleAndObject.first);
while(!grey.empty()) {
while (!grey.empty()) {
GCObjectHandle handle = grey.back();
grey.pop_back();
auto object = objects_[handle];
black[handle] = object;
for(GCObjectHandle refHandle : object->refers())
for (GCObjectHandle refHandle : object->refers())
if (black.find(refHandle) == black.end())
grey.push_back(refHandle);
}
DEBUG << "Removing " << (objects_.size() - black.size())
<< " out of " << objects_.size() << std::endl;
DEBUG << "Removing " << (objects_.size() - black.size()) << " out of " << objects_.size() << std::endl;
// Sweep phase
objects_ = std::move(black);
@ -80,7 +80,6 @@ void GarbageCollector::resume() {
state_ = GCState::Idle;
}
GarbageCollector& getGC() {
static GarbageCollector pool;
return pool;

View File

@ -18,7 +18,8 @@ static const GCObjectHandle GCNull = nullptr;
// Child has to care about storing data and concurrent access.
class GCObject {
public:
GCObject() noexcept : refs_(new std::set<GCObjectHandle>) {}
GCObject() noexcept
: refs_(new std::set<GCObjectHandle>) {}
GCObject(const GCObject& init) = default;
GCObject(GCObject&& init) = default;
virtual ~GCObject() = default;
@ -31,11 +32,7 @@ protected:
std::shared_ptr<std::set<GCObjectHandle>> refs_;
};
enum class GCState {
Idle,
Running,
Stopped
};
enum class GCState { Idle, Running, Stopped };
class GarbageCollector {
public:
@ -43,9 +40,10 @@ public:
~GarbageCollector() = default;
// This method is used to create all managed objects.
template<typename ObjectType,typename... Args>
template <typename ObjectType, typename... Args>
ObjectType create(Args&&... args) {
if (lastCleanup_.fetch_add(1) == step_) cleanup();
if (lastCleanup_.fetch_add(1) == step_)
cleanup();
auto object = std::make_shared<ObjectType>(std::forward<Args>(args)...);
std::lock_guard<std::mutex> g(lock_);
@ -75,7 +73,6 @@ private:
GarbageCollector(const GarbageCollector&) = delete;
};
GarbageCollector& getGC();
} // effil

View File

@ -12,19 +12,16 @@ sol::object createThreadFactory(sol::this_state lua, const sol::function& func)
return sol::make_object(lua, std::make_unique<ThreadFactory>(func));
}
sol::object createShare(sol::this_state lua) {
return sol::make_object(lua, getGC().create<SharedTable>());
}
sol::object createShare(sol::this_state lua) { return sol::make_object(lua, getGC().create<SharedTable>()); }
} // namespace
extern "C" int luaopen_libeffil(lua_State *L) {
extern "C" int luaopen_libeffil(lua_State* L) {
sol::state_view lua(L);
effil::LuaThread::getUserType(lua);
SharedTable::getUserType(lua);
ThreadFactory::getUserType(lua);
sol::table public_api = lua.create_table_with(
"thread", createThreadFactory, //
sol::table public_api = lua.create_table_with("thread", createThreadFactory, //
"thread_id", threadId, //
"sleep", sleep, //
"yield", yield, //
@ -33,4 +30,3 @@ extern "C" int luaopen_libeffil(lua_State *L) {
sol::stack::push(lua, public_api);
return 1;
}

View File

@ -8,21 +8,18 @@
namespace effil {
SharedTable::SharedTable()
: GCObject(),
data_(std::make_shared<SharedData>()) {
}
: GCObject()
, data_(std::make_shared<SharedData>()) {}
SharedTable::SharedTable(const SharedTable& init)
: GCObject(init),
data_(init.data_) {
}
: GCObject(init)
, data_(init.data_) {}
sol::object SharedTable::getUserType(sol::state_view &lua) {
static sol::usertype<SharedTable> type(
"new", sol::no_constructor, //
sol::meta_function::new_index, &SharedTable::luaSet,//
sol::meta_function::index, &SharedTable::luaGet,//
sol::meta_function::length, &SharedTable::length,//
sol::object SharedTable::getUserType(sol::state_view& lua) {
static sol::usertype<SharedTable> type("new", sol::no_constructor, //
sol::meta_function::new_index, &SharedTable::luaSet, //
sol::meta_function::index, &SharedTable::luaGet, //
sol::meta_function::length, &SharedTable::length, //
"__pairs", &SharedTable::pairs, //
"__ipairs", &SharedTable::ipairs //
);
@ -33,8 +30,10 @@ sol::object SharedTable::getUserType(sol::state_view &lua) {
void SharedTable::set(StoredObject&& key, StoredObject&& value) {
std::lock_guard<SpinMutex> g(data_->lock);
if (key->gcHandle()) refs_->insert(key->gcHandle());
if (value->gcHandle()) refs_->insert(value->gcHandle());
if (key->gcHandle())
refs_->insert(key->gcHandle());
if (value->gcHandle())
refs_->insert(value->gcHandle());
data_->entries[std::move(key)] = std::move(value);
}
@ -59,8 +58,10 @@ void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_objec
// in this case object is not obligatory to own data
auto it = data_->entries.find(key);
if (it != data_->entries.end()) {
if (it->first->gcHandle()) refs_->erase(it->first->gcHandle());
if (it->second->gcHandle()) refs_->erase(it->second->gcHandle());
if (it->first->gcHandle())
refs_->erase(it->first->gcHandle());
if (it->second->gcHandle())
refs_->erase(it->second->gcHandle());
data_->entries.erase(it);
}
@ -85,14 +86,12 @@ size_t SharedTable::length() const {
size_t len = 0u;
sol::optional<double> value;
auto iter = data_->entries.find(createStoredObject(static_cast<double>(1)));
if (iter != data_->entries.end())
{
do
{
if (iter != data_->entries.end()) {
do {
++len;
++iter;
}
while ((iter != data_->entries.end()) && (value = storedObjectToDouble(iter->first)) && (static_cast<size_t>(value.value()) == len + 1));
} while ((iter != data_->entries.end()) && (value = storedObjectToDouble(iter->first)) &&
(static_cast<size_t>(value.value()) == len + 1));
}
return len;
}
@ -104,8 +103,7 @@ SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::thi
auto upper = data_->entries.upper_bound(obj);
if (upper != data_->entries.end())
return std::tuple<sol::object, sol::object>(upper->first->unpack(lua), upper->second->unpack(lua));
}
else {
} else {
if (!data_->entries.empty()) {
const auto& begin = data_->entries.begin();
return std::tuple<sol::object, sol::object>(begin->first->unpack(lua), begin->second->unpack(lua));
@ -115,14 +113,16 @@ SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::thi
}
SharedTable::PairsIterator SharedTable::pairs(sol::this_state lua) const {
auto next = [](sol::this_state lua, SharedTable table, sol::stack_object key){ return table.getNext(key, lua); };
auto next = [](sol::this_state lua, SharedTable table, sol::stack_object key) { return table.getNext(key, lua); };
return std::tuple<sol::function, sol::object>(
sol::make_object(lua, std::function<PairsIterator(sol::this_state lua, SharedTable table, sol::stack_object key)>(next)).as<sol::function>(),
sol::make_object(lua, *this)
);
sol::make_object(
lua, std::function<PairsIterator(sol::this_state lua, SharedTable table, sol::stack_object key)>(next))
.as<sol::function>(),
sol::make_object(lua, *this));
}
std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable table, sol::optional<unsigned long> key) {
std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable table,
sol::optional<unsigned long> key) {
size_t index = key ? key.value() + 1 : 1;
auto objKey = createStoredObject(static_cast<double>(index));
sol::object value = table.get(objKey, lua);
@ -132,10 +132,8 @@ std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable
}
std::tuple<sol::function, sol::object> SharedTable::ipairs(sol::this_state lua) const {
return std::tuple<sol::function, sol::object>(
sol::make_object(lua, ipairsNext).as<sol::function>(),
sol::make_object(lua, *this)
);
return std::tuple<sol::function, sol::object>(sol::make_object(lua, ipairsNext).as<sol::function>(),
sol::make_object(lua, *this));
}
} // effil

View File

@ -22,7 +22,7 @@ public:
SharedTable(const SharedTable& init);
virtual ~SharedTable() = default;
static sol::object getUserType(sol::state_view &lua);
static sol::object getUserType(sol::state_view& lua);
void set(StoredObject&&, StoredObject&&);
sol::object get(const StoredObject& key, const sol::this_state& state) const;
PairsIterator getNext(const sol::object& key, sol::this_state lua);
@ -36,7 +36,6 @@ public:
PairsIterator ipairs(sol::this_state) const;
private:
struct SharedData {
SpinMutex lock;
DataEntries entries;
@ -46,4 +45,3 @@ private:
};
} // effil

View File

@ -8,14 +8,12 @@ namespace effil {
class SpinMutex {
public:
void lock() noexcept {
while(lock_.test_and_set(std::memory_order_acquire)) {
while (lock_.test_and_set(std::memory_order_acquire)) {
std::this_thread::yield();
}
}
void unlock() noexcept {
lock_.clear(std::memory_order_release);
}
void unlock() noexcept { lock_.clear(std::memory_order_release); }
private:
std::atomic_flag lock_ = ATOMIC_FLAG_INIT;

View File

@ -13,7 +13,7 @@ namespace effil {
namespace {
template<typename StoredType>
template <typename StoredType>
class PrimitiveHolder : public BaseHolder {
public:
PrimitiveHolder(const sol::stack_object& luaObject) noexcept
@ -29,9 +29,7 @@ public:
return data_ < static_cast<const PrimitiveHolder<StoredType>*>(other)->data_;
}
sol::object unpack(sol::this_state state) const final {
return sol::make_object(state, data_);
}
sol::object unpack(sol::this_state state) const final { return sol::make_object(state, data_); }
StoredType getData() { return data_; }
@ -41,11 +39,12 @@ private:
class FunctionHolder : public BaseHolder {
public:
template<typename SolObject>
template <typename SolObject>
FunctionHolder(SolObject luaObject) noexcept {
sol::state_view lua(luaObject.lua_state());
sol::function dumper = lua["string"]["dump"];
if (!dumper.valid()) throw Exception() << "Invalid string.dump()";
if (!dumper.valid())
throw Exception() << "Invalid string.dump()";
function_ = dumper(luaObject);
}
@ -69,7 +68,7 @@ private:
class TableHolder : public BaseHolder {
public:
template<typename SolType>
template <typename SolType>
TableHolder(const SolType& luaObject) {
assert(luaObject.template is<SharedTable>());
handle_ = luaObject.template as<SharedTable>().handle();
@ -79,7 +78,7 @@ public:
TableHolder(GCObjectHandle handle)
: handle_(handle) {}
bool rawCompare(const BaseHolder *other) const final {
bool rawCompare(const BaseHolder* other) const final {
return handle_ < static_cast<const TableHolder*>(other)->handle_;
}
@ -103,7 +102,7 @@ void dumpTable(SharedTable* target, sol::table luaTable, SolTableToShared& visit
StoredObject makeStoredObject(sol::object luaObject, SolTableToShared& visited) {
if (luaObject.get_type() == sol::type::table) {
sol::table luaTable = luaObject;
auto comparator = [&luaTable](const std::pair<sol::table, GCObjectHandle>& element){
auto comparator = [&luaTable](const std::pair<sol::table, GCObjectHandle>& element) {
return element.first == luaTable;
};
auto st = std::find_if(visited.begin(), visited.end(), comparator);
@ -122,14 +121,14 @@ StoredObject makeStoredObject(sol::object luaObject, SolTableToShared& visited)
}
void dumpTable(SharedTable* target, sol::table luaTable, SolTableToShared& visited) {
for(auto& row : luaTable) {
for (auto& row : luaTable) {
target->set(makeStoredObject(row.first, visited), makeStoredObject(row.second, visited));
}
}
template<typename SolObject>
template <typename SolObject>
StoredObject fromSolObject(const SolObject& luaObject) {
switch(luaObject.get_type()) {
switch (luaObject.get_type()) {
case sol::type::nil:
break;
case sol::type::boolean:
@ -142,8 +141,7 @@ StoredObject fromSolObject(const SolObject& luaObject) {
return std::make_unique<TableHolder>(luaObject);
case sol::type::function:
return std::make_unique<FunctionHolder>(luaObject);
case sol::type::table:
{
case sol::type::table: {
sol::table luaTable = luaObject;
// Tables pool is used to store tables.
// Right now not defiantly clear how ownership between states works.
@ -164,31 +162,21 @@ StoredObject fromSolObject(const SolObject& luaObject) {
} // namespace
StoredObject createStoredObject(bool value) {
return std::make_unique<PrimitiveHolder<bool>>(value);
}
StoredObject createStoredObject(bool value) { return std::make_unique<PrimitiveHolder<bool>>(value); }
StoredObject createStoredObject(double value) {
return std::make_unique<PrimitiveHolder<double>>(value);
}
StoredObject createStoredObject(double value) { return std::make_unique<PrimitiveHolder<double>>(value); }
StoredObject createStoredObject(const std::string& value) {
return std::make_unique<PrimitiveHolder<std::string>>(value);
}
StoredObject createStoredObject(const sol::object &object) {
return fromSolObject(object);
}
StoredObject createStoredObject(const sol::object& object) { return fromSolObject(object); }
StoredObject createStoredObject(const sol::stack_object &object) {
return fromSolObject(object);
}
StoredObject createStoredObject(const sol::stack_object& object) { return fromSolObject(object); }
StoredObject createStoredObject(GCObjectHandle handle) {
return std::make_unique<TableHolder>(handle);
}
StoredObject createStoredObject(GCObjectHandle handle) { return std::make_unique<TableHolder>(handle); }
template<typename DataType>
template <typename DataType>
sol::optional<DataType> getPrimitiveHolderData(const StoredObject& sobj) {
auto ptr = dynamic_cast<PrimitiveHolder<DataType>*>(sobj.get());
if (ptr)
@ -196,13 +184,9 @@ sol::optional<DataType> getPrimitiveHolderData(const StoredObject& sobj) {
return sol::optional<DataType>();
}
sol::optional<bool> storedObjectToBool(const StoredObject& sobj) {
return getPrimitiveHolderData<bool>(sobj);
}
sol::optional<bool> storedObjectToBool(const StoredObject& sobj) { return getPrimitiveHolderData<bool>(sobj); }
sol::optional<double> storedObjectToDouble(const StoredObject& sobj) {
return getPrimitiveHolderData<double>(sobj);
}
sol::optional<double> storedObjectToDouble(const StoredObject& sobj) { return getPrimitiveHolderData<double>(sobj); }
sol::optional<std::string> storedObjectToString(const StoredObject& sobj) {
return getPrimitiveHolderData<std::string>(sobj);

View File

@ -30,17 +30,15 @@ private:
typedef std::unique_ptr<BaseHolder> StoredObject;
struct StoredObjectLess {
bool operator()(const StoredObject& lhs, const StoredObject& rhs) const {
return lhs->compare(rhs.get());
}
bool operator()(const StoredObject& lhs, const StoredObject& rhs) const { return lhs->compare(rhs.get()); }
};
StoredObject createStoredObject(bool);
StoredObject createStoredObject(double);
StoredObject createStoredObject(const std::string&);
StoredObject createStoredObject(GCObjectHandle);
StoredObject createStoredObject(const sol::object &);
StoredObject createStoredObject(const sol::stack_object &);
StoredObject createStoredObject(const sol::object&);
StoredObject createStoredObject(const sol::stack_object&);
sol::optional<bool> storedObjectToBool(const StoredObject&);
sol::optional<double> storedObjectToDouble(const StoredObject&);

View File

@ -7,20 +7,15 @@ namespace effil {
class LuaHookStopException : public std::exception {};
std::string threadId()
{
std::string threadId() {
std::stringstream ss;
ss << std::this_thread::get_id();
return ss.str();
}
void yield()
{
std::this_thread::yield();
}
void yield() { std::this_thread::yield(); }
void sleep(int64_t time, sol::optional<std::string> period)
{
void sleep(int64_t time, sol::optional<std::string> period) {
std::string metric = period ? period.value() : "s";
if (metric == "ms")
std::this_thread::sleep_for(std::chrono::milliseconds(time));
@ -36,14 +31,15 @@ thread_local LuaThread::ThreadData* LuaThread::pThreadLocalData = NULL;
// class LuaThread
LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args) {
LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function,
const sol::variadic_args& args) {
pThreadData_ = threadData;
assert(pThreadData_);
pThreadData_->command = ThreadCommand::Nothing;
pThreadData_->status = ThreadStatus::Running;
std::vector<sol::object> arguments;
for(const auto& iter: args) {
for (const auto& iter : args) {
StoredObject store = createStoredObject(iter.get<sol::object>());
arguments.push_back(store->unpack(sol::this_state{pThreadData_->luaState}));
}
@ -53,14 +49,10 @@ LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string&
pThread_->detach();
}
void LuaThread::luaHook(lua_State*, lua_Debug*)
{
if (pThreadLocalData)
{
switch (pThreadLocalData->command)
{
case ThreadCommand::Pause:
{
void LuaThread::luaHook(lua_State*, lua_Debug*) {
if (pThreadLocalData) {
switch (pThreadLocalData->command) {
case ThreadCommand::Pause: {
pThreadLocalData->status = ThreadStatus::Paused;
ThreadCommand cmd = pThreadLocalData->command;
while (cmd == ThreadCommand::Pause) {
@ -68,12 +60,11 @@ void LuaThread::luaHook(lua_State*, lua_Debug*)
cmd = pThreadLocalData->command;
}
assert(cmd != ThreadCommand::Nothing);
if (cmd == ThreadCommand::Resume)
{
if (cmd == ThreadCommand::Resume) {
pThreadLocalData->status = ThreadStatus::Running;
break; // Just go out of the function
} else { /* HOOK_STOP - do nothing and go to the next case */
}
else { /* HOOK_STOP - do nothing and go to the next case */}
}
case ThreadCommand::Cancel:
throw LuaHookStopException();
@ -84,26 +75,26 @@ void LuaThread::luaHook(lua_State*, lua_Debug*)
}
}
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments) {
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction,
std::vector<sol::object>&& arguments) {
try {
pThreadLocalData = threadData.get();
assert(threadData);
const sol::object& stringLoader = threadData->luaState["loadstring"];
REQUIRE(stringLoader.valid() && stringLoader.get_type() == sol::type::function) << "Invalid loadstring function";
REQUIRE(stringLoader.valid() && stringLoader.get_type() == sol::type::function)
<< "Invalid loadstring function";
sol::function userFuncObj = static_cast<const sol::function&>(stringLoader)(strFunction);
sol::function_result results = userFuncObj(sol::as_args(arguments));
(void)results; // TODO: try to avoid use of useless sol::function_result here
sol::variadic_args args(threadData->luaState, -lua_gettop(threadData->luaState));
for(const auto& iter: args) {
for (const auto& iter : args) {
StoredObject store = createStoredObject(iter.get<sol::object>());
threadData->results.emplace_back(std::move(store));
}
threadData->status = ThreadStatus::Completed;
}
catch (const LuaHookStopException&) {
} catch (const LuaHookStopException&) {
threadData->status = ThreadStatus::Canceled;
}
catch (const sol::error& err) {
} catch (const sol::error& err) {
threadData->status = ThreadStatus::Failed;
sol::stack::push(threadData->luaState, err.what());
StoredObject store = createStoredObject(sol::stack::pop<sol::object>(threadData->luaState));
@ -111,23 +102,13 @@ void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string s
}
}
void LuaThread::cancel()
{
pThreadData_->command = ThreadCommand::Cancel;
}
void LuaThread::cancel() { pThreadData_->command = ThreadCommand::Cancel; }
void LuaThread::pause()
{
pThreadData_->command = ThreadCommand::Pause;
}
void LuaThread::pause() { pThreadData_->command = ThreadCommand::Pause; }
void LuaThread::resume()
{
pThreadData_->command = ThreadCommand::Resume;
}
void LuaThread::resume() { pThreadData_->command = ThreadCommand::Resume; }
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
{
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const {
ThreadStatus stat = pThreadData_->status;
while (stat == ThreadStatus::Running) {
@ -135,52 +116,49 @@ std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
stat = pThreadData_->status;
}
sol::table returns = sol::state_view(state).create_table();
if (stat == ThreadStatus::Completed)
{
for (const StoredObject& obj: pThreadData_->results)
{
if (stat == ThreadStatus::Completed) {
for (const StoredObject& obj : pThreadData_->results) {
returns.add(obj->unpack(state));
}
}
return std::make_tuple(sol::make_object(state, threadStatusToString(stat)), std::move(returns));
}
std::string LuaThread::threadStatusToString(ThreadStatus stat) const
{
switch(stat)
{
case ThreadStatus::Running: return "running";
case ThreadStatus::Paused: return "paused";
case ThreadStatus::Canceled: return "canceled";
case ThreadStatus::Completed: return "completed";
case ThreadStatus::Failed: return "failed";
std::string LuaThread::threadStatusToString(ThreadStatus stat) const {
switch (stat) {
case ThreadStatus::Running:
return "running";
case ThreadStatus::Paused:
return "paused";
case ThreadStatus::Canceled:
return "canceled";
case ThreadStatus::Completed:
return "completed";
case ThreadStatus::Failed:
return "failed";
}
assert(false);
return "unknown";
}
std::string LuaThread::status() const
{
return threadStatusToString(pThreadData_->status);
}
std::string LuaThread::status() const { return threadStatusToString(pThreadData_->status); }
sol::object LuaThread::getUserType(sol::state_view &lua)
{
static sol::usertype<LuaThread> type(
"new", sol::no_constructor, //
sol::object LuaThread::getUserType(sol::state_view& lua) {
static sol::usertype<LuaThread> type("new", sol::no_constructor, //
"cancel", &LuaThread::cancel, //
"pause", &LuaThread::pause, //
"resume", &LuaThread::resume, //
"status", &LuaThread::status, //
"wait", &LuaThread::wait
);
"wait", &LuaThread::wait);
sol::stack::push(lua, type);
return sol::stack::pop<sol::object>(lua);
}
// class ThreadFactory
ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step_(100U) {
ThreadFactory::ThreadFactory(const sol::function& func)
: stepwise_(false)
, step_(100U) {
sol::state_view lua(func.lua_state());
const sol::object& dumper = lua["string"]["dump"];
REQUIRE(dumper.valid() && dumper.get_type() == sol::type::function) << "Unable to get string.dump()";
@ -194,10 +172,8 @@ ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step
std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& args) {
std::shared_ptr<LuaThread::ThreadData> threadData = std::make_shared<LuaThread::ThreadData>();
assert(threadData.get());
threadData->luaState.open_libraries(
sol::lib::base, sol::lib::string,
sol::lib::package, sol::lib::io, sol::lib::os
);
threadData->luaState.open_libraries(sol::lib::base, sol::lib::string, sol::lib::package, sol::lib::io,
sol::lib::os);
if (stepwise_)
lua_sethook(threadData->luaState, LuaThread::luaHook, LUA_MASKCOUNT, step_);
@ -213,43 +189,37 @@ std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& ar
return std::make_unique<LuaThread>(threadData, strFunction_, args);
}
bool ThreadFactory::stepwise(const sol::optional<bool>& value)
{
bool ret = stepwise_ ;
bool ThreadFactory::stepwise(const sol::optional<bool>& value) {
bool ret = stepwise_;
if (value)
stepwise_ = value.value();
return ret;
}
unsigned int ThreadFactory::step(const sol::optional<unsigned int>& value)
{
unsigned int ThreadFactory::step(const sol::optional<unsigned int>& value) {
bool ret = step_;
if (value)
step_ = value.value();
return ret;
}
std::string ThreadFactory::packagePath(const sol::optional<std::string>& value)
{
std::string ThreadFactory::packagePath(const sol::optional<std::string>& value) {
std::string& ret = packagePath_;
if (value)
packagePath_ = value.value();
return ret;
}
std::string ThreadFactory::packageCPath(const sol::optional<std::string>& value)
{
std::string ThreadFactory::packageCPath(const sol::optional<std::string>& value) {
std::string& ret = packageCPath_;
if (value)
packageCPath_ = value.value();
return ret;
}
sol::object ThreadFactory::getUserType(sol::state_view &lua)
{
static sol::usertype<ThreadFactory> type(
"new", sol::no_constructor, //
sol::meta_function::call, &ThreadFactory::runThread,//
sol::object ThreadFactory::getUserType(sol::state_view& lua) {
static sol::usertype<ThreadFactory> type("new", sol::no_constructor, //
sol::meta_function::call, &ThreadFactory::runThread, //
"stepwise", &ThreadFactory::stepwise, //
"step", &ThreadFactory::step, //
"package_path", &ThreadFactory::packagePath, //

View File

@ -23,15 +23,14 @@ public:
Failed,
};
enum class ThreadCommand
{
enum class ThreadCommand {
Nothing = 1,
Cancel,
Pause,
Resume,
};
struct ThreadData{
struct ThreadData {
sol::state luaState;
std::atomic<ThreadStatus> status;
std::atomic<ThreadCommand> command;
@ -39,7 +38,7 @@ public:
};
LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args);
static sol::object getUserType(sol::state_view &lua);
static sol::object getUserType(sol::state_view& lua);
static void luaHook(lua_State*, lua_Debug*);
/* Public lua methods*/
@ -54,7 +53,8 @@ private:
LuaThread& operator=(const LuaThread&) = delete;
std::string threadStatusToString(ThreadStatus stat) const;
static void work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments);
static void work(std::shared_ptr<ThreadData> threadData, const std::string strFunction,
std::vector<sol::object>&& arguments);
std::shared_ptr<ThreadData> pThreadData_;
std::shared_ptr<std::thread> pThread_;
@ -65,7 +65,7 @@ private:
class ThreadFactory {
public:
ThreadFactory(const sol::function& func);
static sol::object getUserType(sol::state_view &lua);
static sol::object getUserType(sol::state_view& lua);
/* Public lua methods*/
std::unique_ptr<LuaThread> runThread(const sol::variadic_args& args);

View File

@ -9,9 +9,10 @@ namespace effil {
class Exception : public sol::error {
public:
Exception() noexcept : sol::error("") {}
Exception() noexcept
: sol::error("") {}
template<typename T>
template <typename T>
Exception& operator<<(const T& value) {
std::stringstream ss;
ss << value;
@ -19,9 +20,7 @@ public:
return *this;
}
virtual const char* what() const noexcept override {
return message_.c_str();
}
virtual const char* what() const noexcept override { return message_.c_str(); }
private:
std::string message_;
@ -29,10 +28,14 @@ private:
} // effil
#define REQUIRE(cond) if (!cond) throw effil::Exception()
#define REQUIRE(cond) \
if (!cond) \
throw effil::Exception()
#ifdef NDEBUG
# define DEBUG if (false) std::cout
#define DEBUG \
if (false) \
std::cout
#else
# define DEBUG std::cout
#define DEBUG std::cout
#endif

View File

@ -29,8 +29,10 @@ TEST(gc, collect) {
ASSERT_EQ(getGC().size(), (size_t)0);
{
GCObject o1 = getGC().create<GCObject>();;
GCObject o2 = getGC().create<GCObject>();;
GCObject o1 = getGC().create<GCObject>();
;
GCObject o2 = getGC().create<GCObject>();
;
}
EXPECT_EQ(getGC().size(), (size_t)2);
getGC().cleanup();
@ -42,7 +44,6 @@ namespace {
struct Dummy : public GCObject {
void add(GCObjectHandle ref) { refs_->insert(ref); }
};
}
TEST(gc, withRefs) {
@ -52,14 +53,14 @@ TEST(gc, withRefs) {
{
Dummy orphan = getGC().create<Dummy>();
for(size_t i = 0; i < 3; i++) {
for (size_t i = 0; i < 3; i++) {
Dummy child = getGC().create<Dummy>();
root.add(child.handle());
}
}
EXPECT_EQ(getGC().size(), (size_t) 5);
EXPECT_EQ(getGC().size(), (size_t)5);
getGC().cleanup();
EXPECT_EQ(getGC().size(), (size_t) 4);
EXPECT_EQ(getGC().size(), (size_t)4);
}
getGC().cleanup();
EXPECT_EQ(getGC().size(), (size_t)0);
@ -69,13 +70,14 @@ TEST(gc, autoCleanup) {
std::vector<std::thread> threads;
size_t objectsPerThread = 1000;
for(size_t i = 0; i < 5; i++)
threads.emplace_back([=]{
for(size_t i = 0; i < objectsPerThread; i++)
for (size_t i = 0; i < 5; i++)
threads.emplace_back([=] {
for (size_t i = 0; i < objectsPerThread; i++)
getGC().create<GCObject>();
});
for(auto& thread : threads) thread.join();
for (auto& thread : threads)
thread.join();
EXPECT_LT(getGC().size(), getGC().step());
}
@ -92,7 +94,7 @@ end
)");
EXPECT_EQ(getGC().size(), (size_t)1001);
lua.script(R"(
lua.script(R"(
for i=1,1000 do
st[i] = nil
end

View File

@ -80,16 +80,17 @@ TEST(sharedTable, multipleThreads) {
std::vector<std::thread> threads;
threads.emplace_back([=](){
threads.emplace_back([=]() {
sol::state lua;
bootstrapState(lua);;
bootstrapState(lua);
;
lua["st"] = st;
lua.script(R"(
while not st.ready do end
st.fst = true)");
});
threads.emplace_back([=](){
threads.emplace_back([=]() {
sol::state lua;
bootstrapState(lua);
lua["st"] = st;
@ -98,7 +99,7 @@ while not st.ready do end
st.snd = true)");
});
threads.emplace_back([=](){
threads.emplace_back([=]() {
sol::state lua;
bootstrapState(lua);
lua["st"] = st;
@ -112,7 +113,9 @@ st.thr = true)");
lua["st"] = st;
lua.script("st.ready = true");
for(auto& thread : threads) { thread.join(); }
for (auto& thread : threads) {
thread.join();
}
EXPECT_EQ(lua["st"]["fst"], true);
EXPECT_EQ(lua["st"]["snd"], true);
@ -235,7 +238,7 @@ TEST(sharedTable, stressWithThreads) {
const size_t threadCount = 10;
std::vector<std::thread> threads;
for(size_t i = 0; i < threadCount; i++) {
for (size_t i = 0; i < threadCount; i++) {
threads.emplace_back([=] {
sol::state lua;
bootstrapState(lua);
@ -243,20 +246,21 @@ TEST(sharedTable, stressWithThreads) {
std::stringstream ss;
ss << "st[" << i << "] = 1" << std::endl;
ss << "for i = 1, 100000 do" << std::endl;
ss << " st[" << i << "] = " << "st[" << i << "] + 1" << std::endl;
ss << " st[" << i << "] = "
<< "st[" << i << "] + 1" << std::endl;
ss << "end" << std::endl;
lua.script(ss.str());
});
}
for(auto& thread : threads) {
for (auto& thread : threads) {
thread.join();
}
sol::state lua;
bootstrapState(lua);
lua["st"] = st;
for(size_t i = 0; i < threadCount; i++) {
for (size_t i = 0; i < threadCount; i++) {
EXPECT_TRUE(lua["st"][i] == 100'001) << (double)lua["st"][i] << std::endl;
}
}

View File

@ -1,6 +1,6 @@
#include "gtest/gtest.h"
int main(int argc, char **argv) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -6,11 +6,7 @@
namespace effil {
inline void bootstrapState(sol::state& lua) {
lua.open_libraries(
sol::lib::base,
sol::lib::string,
sol::lib::table
);
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::table);
SharedTable::getUserType(lua);
}