system/luaserver: Terminate Lua script when luaclient dies.

This commit is contained in:
martii
2014-10-13 22:11:25 +02:00
committed by svenhoefer
parent d681936f26
commit ffec667030
4 changed files with 55 additions and 17 deletions

View File

@@ -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 },

View File

@@ -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*

View File

@@ -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) {

View File

@@ -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();