mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-28 07:51:19 +02:00
system/luaserver: Terminate Lua script when luaclient dies.
This commit is contained in:
@@ -480,6 +480,16 @@ void CLuaInstance::runScript(const char *fileName, const char *arg0, ...)
|
|||||||
args.clear();
|
args.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void abortHook(lua_State *lua, lua_Debug *)
|
||||||
|
{
|
||||||
|
luaL_error(lua, "aborted");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLuaInstance::abortScript()
|
||||||
|
{
|
||||||
|
lua_sethook(lua, &abortHook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg CLuaInstance::methods[] =
|
const luaL_Reg CLuaInstance::methods[] =
|
||||||
{
|
{
|
||||||
{ "PaintBox", CLuaInstance::PaintBox },
|
{ "PaintBox", CLuaInstance::PaintBox },
|
||||||
|
@@ -176,6 +176,7 @@ public:
|
|||||||
CLuaInstance();
|
CLuaInstance();
|
||||||
~CLuaInstance();
|
~CLuaInstance();
|
||||||
void runScript(const char *fileName, std::vector<std::string> *argv = NULL, std::string *result_code = NULL, std::string *result_string = NULL, std::string *error_string = NULL);
|
void runScript(const char *fileName, std::vector<std::string> *argv = NULL, std::string *result_code = NULL, std::string *result_string = NULL, std::string *error_string = NULL);
|
||||||
|
void abortScript();
|
||||||
|
|
||||||
// Example: runScript(fileName, "Arg1", "Arg2", "Arg3", ..., NULL);
|
// Example: runScript(fileName, "Arg1", "Arg2", "Arg3", ..., NULL);
|
||||||
// Type of all parameters: const char*
|
// Type of all parameters: const char*
|
||||||
|
@@ -114,7 +114,10 @@ bool CLuaServer::Block(const neutrino_msg_t msg, const neutrino_msg_data_t data)
|
|||||||
class luaserver_data
|
class luaserver_data
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CLuaInstance *lua;
|
||||||
|
bool died;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
std::vector<std::string> argv;
|
std::vector<std::string> argv;
|
||||||
std::string script;
|
std::string script;
|
||||||
|
|
||||||
@@ -122,6 +125,7 @@ class luaserver_data
|
|||||||
fd = dup(_fd);
|
fd = dup(_fd);
|
||||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
script = _script;
|
script = _script;
|
||||||
|
died = false;
|
||||||
}
|
}
|
||||||
~luaserver_data(void) {
|
~luaserver_data(void) {
|
||||||
close(fd);
|
close(fd);
|
||||||
@@ -138,6 +142,21 @@ void CLuaServer::UnLock(void)
|
|||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *CLuaServer::luaclient_watchdog(void *arg) {
|
||||||
|
set_threadname(__func__);
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||||
|
|
||||||
|
luaserver_data *lsd = (class luaserver_data *)arg;
|
||||||
|
|
||||||
|
struct pollfd pfd;
|
||||||
|
pfd.fd = lsd->fd;
|
||||||
|
pfd.events = pfd.revents = 0;
|
||||||
|
poll(&pfd, 1, -1);
|
||||||
|
lsd->lua->abortScript();
|
||||||
|
lsd->died = true;
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void *CLuaServer::luaserver_thread(void *arg) {
|
void *CLuaServer::luaserver_thread(void *arg) {
|
||||||
set_threadname(__func__);
|
set_threadname(__func__);
|
||||||
Lock();
|
Lock();
|
||||||
@@ -149,28 +168,35 @@ void *CLuaServer::luaserver_thread(void *arg) {
|
|||||||
|
|
||||||
luaserver_data *lsd = (class luaserver_data *)arg;
|
luaserver_data *lsd = (class luaserver_data *)arg;
|
||||||
|
|
||||||
|
pthread_t wdthr;
|
||||||
|
pthread_create (&wdthr, NULL, luaclient_watchdog, (void *) lsd);
|
||||||
|
|
||||||
CLuaInstance lua;
|
CLuaInstance lua;
|
||||||
|
lsd->lua = &lua;
|
||||||
std::string result_code;
|
std::string result_code;
|
||||||
std::string result_string;
|
std::string result_string;
|
||||||
std::string error_string;
|
std::string error_string;
|
||||||
lua.runScript(lsd->script.c_str(), &lsd->argv, &result_code, &result_string, &error_string);
|
lua.runScript(lsd->script.c_str(), &lsd->argv, &result_code, &result_string, &error_string);
|
||||||
size_t result_code_len = result_code.length() + 1;
|
pthread_cancel(wdthr);
|
||||||
size_t result_string_len = result_string.length() + 1;
|
pthread_join(wdthr, NULL);
|
||||||
size_t error_string_len = error_string.length() + 1;
|
if (!lsd->died) {
|
||||||
size_t size = result_code_len + result_string_len + error_string_len;
|
size_t result_code_len = result_code.length() + 1;
|
||||||
char result[size + sizeof(size)];
|
size_t result_string_len = result_string.length() + 1;
|
||||||
char *rp = result;
|
size_t error_string_len = error_string.length() + 1;
|
||||||
memcpy(rp, &size, sizeof(size));
|
size_t size = result_code_len + result_string_len + error_string_len;
|
||||||
rp += sizeof(size);
|
char result[size + sizeof(size)];
|
||||||
size += sizeof(size);
|
char *rp = result;
|
||||||
memcpy(rp, result_code.c_str(), result_code_len);
|
memcpy(rp, &size, sizeof(size));
|
||||||
rp += result_code_len;
|
rp += sizeof(size);
|
||||||
memcpy(rp, result_string.c_str(), result_string_len);
|
size += sizeof(size);
|
||||||
rp += result_string_len;
|
memcpy(rp, result_code.c_str(), result_code_len);
|
||||||
memcpy(rp, error_string.c_str(), error_string_len);
|
rp += result_code_len;
|
||||||
rp += error_string_len;
|
memcpy(rp, result_string.c_str(), result_string_len);
|
||||||
CBasicServer::send_data(lsd->fd, result, size);
|
rp += result_string_len;
|
||||||
|
memcpy(rp, error_string.c_str(), error_string_len);
|
||||||
|
rp += error_string_len;
|
||||||
|
CBasicServer::send_data(lsd->fd, result, size);
|
||||||
|
}
|
||||||
delete lsd;
|
delete lsd;
|
||||||
Lock();
|
Lock();
|
||||||
if (instance) {
|
if (instance) {
|
||||||
|
@@ -32,6 +32,7 @@ class CLuaServer
|
|||||||
|
|
||||||
static void *luaserver_thread(void *arg);
|
static void *luaserver_thread(void *arg);
|
||||||
static void *luaserver_main_thread(void *);
|
static void *luaserver_main_thread(void *);
|
||||||
|
static void *luaclient_watchdog(void *);
|
||||||
static bool luaserver_parse_command(CBasicMessage::Header &rmsg, int connfd);
|
static bool luaserver_parse_command(CBasicMessage::Header &rmsg, int connfd);
|
||||||
static void Lock();
|
static void Lock();
|
||||||
static void UnLock();
|
static void UnLock();
|
||||||
|
Reference in New Issue
Block a user