1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| void wxbox::plugin::internal::PluginVirtualMachineHookHandler(lua_State* L, lua_Debug* debugInfo) { WXBOX_UNREF(debugInfo);
lua_sethook(L, NULL, 0, 0); luaL_error(L, "plugin virtual machine long task timeout"); }
std::time_t GetCurrentTimestamp() { auto t = std::chrono::system_clock::now().time_since_epoch(); return std::chrono::duration_cast<std::chrono::milliseconds>(t).count(); }
#define BEGIN_PLUGIN_VIRTUAL_MACHINE_LONG_TASK_WITH_TIMEOUT(vm) \ { \ auto __task_begin_timestamp = GetCurrentTimestamp(); \ std::promise<void> __task_complete_signal; \ \ auto __task_async_future = std::async( \ std::launch::async, [__task_begin_timestamp, vm](std::future<void> taskFuture) { \ for (;;) { \ if (taskFuture.wait_for(std::chrono::milliseconds(10)) != std::future_status::timeout) { \ \ break; \ } \ \ if (GetCurrentTimestamp() - __task_begin_timestamp >= vm->longTaskTimeout) { \ \ lua_sethook(vm->state, PluginVirtualMachineHookHandler, LUA_MASKLINE, 0); \ break; \ } \ } \ }, \ std::move(__task_complete_signal.get_future()));
#define END_PLUGIN_VIRTUAL_MACHINE_LONG_TASK_WITH_TIMEOUT(vm) \ CANCEL_PLUGIN_VIRTUAL_MACHINE_LONG_TASK(vm); \ }
#define CANCEL_PLUGIN_VIRTUAL_MACHINE_LONG_TASK(vm) \ { \ __task_complete_signal.set_value(); \ __task_async_future.wait(); \ lua_sethook(vm->state, NULL, 0, 0); \ }
|