Cancel in yield 2 (#50)
This commit is contained in:
parent
265b12370b
commit
6b77d9f9ec
@ -24,7 +24,7 @@ endif()
|
||||
add_library(effil SHARED ${SOURCES})
|
||||
target_link_libraries(effil -lpthread ${LUA_LIBRARY})
|
||||
|
||||
set(GENERAL "-std=c++14")
|
||||
set(GENERAL "-std=c++14 -DSOL_EXCEPTIONS_SAFE_PROPAGATION")
|
||||
set(ENABLE_WARNINGS "-Wall -Wextra -pedantic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GENERAL} ${ENABLE_WARNINGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -O0 -g -UNDEBUG")
|
||||
|
||||
@ -12,11 +12,10 @@ namespace {
|
||||
sol::object createThread(const sol::this_state& lua,
|
||||
const std::string& path,
|
||||
const std::string& cpath,
|
||||
bool stepwise,
|
||||
unsigned int step,
|
||||
int step,
|
||||
const sol::function& function,
|
||||
const sol::variadic_args& args) {
|
||||
return sol::make_object(lua, std::make_shared<Thread>(path, cpath, stepwise, step, function, args));
|
||||
return sol::make_object(lua, std::make_shared<Thread>(path, cpath, step, function, args));
|
||||
}
|
||||
|
||||
sol::object createTable(sol::this_state lua) {
|
||||
|
||||
@ -49,11 +49,8 @@ enum class Command {
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
class ThreadHandle {
|
||||
public:
|
||||
const bool managed;
|
||||
|
||||
Status status;
|
||||
StoredArray result;
|
||||
|
||||
@ -64,9 +61,8 @@ public:
|
||||
Notifier syncPause;
|
||||
|
||||
public:
|
||||
ThreadHandle(bool isManaged)
|
||||
: managed(isManaged)
|
||||
, status(Status::Running)
|
||||
ThreadHandle()
|
||||
: status(Status::Running)
|
||||
, command_(Command::Run)
|
||||
, lua_(std::make_unique<sol::state>()) {
|
||||
luaL_openlibs(*lua_);
|
||||
@ -171,7 +167,11 @@ std::string threadId() {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void yield() { std::this_thread::yield(); }
|
||||
void yield() {
|
||||
if (thisThreadHandle)
|
||||
luaHook(nullptr, nullptr);
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
void sleep(const sol::optional<int>& duration, const sol::optional<std::string>& period) {
|
||||
if (duration)
|
||||
@ -182,17 +182,16 @@ void sleep(const sol::optional<int>& duration, const sol::optional<std::string>&
|
||||
|
||||
Thread::Thread(const std::string& path,
|
||||
const std::string& cpath,
|
||||
bool managed,
|
||||
unsigned int step,
|
||||
int step,
|
||||
const sol::function& function,
|
||||
const sol::variadic_args& variadicArgs)
|
||||
: handle_(std::make_shared<ThreadHandle>(managed)) {
|
||||
: handle_(std::make_shared<ThreadHandle>()) {
|
||||
|
||||
handle_->lua()["package"]["path"] = path;
|
||||
handle_->lua()["package"]["cpath"] = cpath;
|
||||
handle_->lua().script("require 'effil'");
|
||||
|
||||
if (managed)
|
||||
if (step != 0)
|
||||
lua_sethook(handle_->lua(), luaHook, LUA_MASKCOUNT, step);
|
||||
|
||||
std::string strFunction = dumpFunction(function);
|
||||
@ -264,8 +263,6 @@ StoredArray Thread::get(const sol::optional<int>& duration,
|
||||
bool Thread::cancel(const sol::this_state&,
|
||||
const sol::optional<int>& duration,
|
||||
const sol::optional<std::string>& period) {
|
||||
REQUIRE(handle_->managed) << "Unable to cancel: unmanaged thread";
|
||||
|
||||
handle_->command(Command::Cancel);
|
||||
handle_->pause.notify();
|
||||
|
||||
@ -280,8 +277,6 @@ bool Thread::cancel(const sol::this_state&,
|
||||
bool Thread::pause(const sol::this_state&,
|
||||
const sol::optional<int>& duration,
|
||||
const sol::optional<std::string>& period) {
|
||||
REQUIRE(handle_->managed) << "Unable to pause: unmanaged thread";
|
||||
|
||||
handle_->pause.reset();
|
||||
handle_->command(Command::Pause);
|
||||
|
||||
@ -294,8 +289,6 @@ bool Thread::pause(const sol::this_state&,
|
||||
}
|
||||
|
||||
void Thread::resume() {
|
||||
REQUIRE(handle_->managed) << "Unable to resume: unmanaged thread";
|
||||
|
||||
handle_->command(Command::Run);
|
||||
handle_->syncPause.reset();
|
||||
handle_->pause.notify();
|
||||
|
||||
@ -16,8 +16,7 @@ class Thread {
|
||||
public:
|
||||
Thread(const std::string& path,
|
||||
const std::string& cpath,
|
||||
bool managed,
|
||||
unsigned int step,
|
||||
int step,
|
||||
const sol::function& function,
|
||||
const sol::variadic_args& args);
|
||||
|
||||
|
||||
@ -37,21 +37,19 @@ api.type = function (something)
|
||||
end
|
||||
|
||||
local function run_thread(config, f, ...)
|
||||
return capi.thread(config.path, config.cpath, config.managed, config.step, f, ...)
|
||||
return capi.thread(config.path, config.cpath, config.step, f, ...)
|
||||
end
|
||||
|
||||
-- Creates thread runner with given function
|
||||
-- configurable parameters:
|
||||
-- path - lua modules search path in child thread
|
||||
-- cpath - lua libs search path in child thread
|
||||
-- stepwise - is thread resumable
|
||||
-- step - who fast reacte on state changing
|
||||
-- __call - run thread, can be invoked multiple times
|
||||
api.thread = function (f)
|
||||
local thread_config = {
|
||||
path = package.path,
|
||||
cpath = package.cpath,
|
||||
managed = true,
|
||||
step = 200 }
|
||||
setmetatable(thread_config, {__call = function(c, ...) return run_thread(c, f, ...) end})
|
||||
return thread_config
|
||||
|
||||
@ -279,5 +279,45 @@ test.this_thread.functions = function ()
|
||||
test.is_string(share["child.id"])
|
||||
test.is_number(tonumber(share["child.id"]))
|
||||
test.not_equal(share["child.id"], effil.thread_id())
|
||||
effil.yield() -- just call it
|
||||
end
|
||||
|
||||
test.this_thread.cancel_with_yield = function ()
|
||||
local share = effil.table()
|
||||
local spec = effil.thread(function (share)
|
||||
require('effil').sleep(1)
|
||||
for i=1,10000 do
|
||||
-- Just waiting
|
||||
end
|
||||
share.done = true
|
||||
require("effil").yield()
|
||||
share.afet_yield = true
|
||||
end)
|
||||
spec.step = 0
|
||||
local thr = spec(share)
|
||||
|
||||
test.is_true(thr:cancel())
|
||||
test.equal(thr:status(), "canceled")
|
||||
test.is_true(share.done)
|
||||
test.is_nil(share.afet_yield)
|
||||
end
|
||||
|
||||
test.this_thread.pause_with_yield = function ()
|
||||
local share = effil.table()
|
||||
local spec = effil.thread(function (share)
|
||||
for i=1,10000 do
|
||||
require("effil").yield()
|
||||
end
|
||||
share.done = true
|
||||
return true
|
||||
end)
|
||||
spec.step = 0
|
||||
local thr = spec(share)
|
||||
|
||||
thr:pause()
|
||||
test.is_nil(share.done)
|
||||
test.equal(thr:status(), "paused")
|
||||
thr:resume()
|
||||
|
||||
test.is_true(thr:get())
|
||||
test.is_true(share.done)
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user