From a41c6c12ba0a3db297ae945b0700d48e2d1905f8 Mon Sep 17 00:00:00 2001 From: Pixel Date: Mon, 5 Oct 2009 16:54:34 -0700 Subject: Adding the newthread() call for a fully pthreaded lua environment. --- src/lua-interface.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) (limited to 'src/lua-interface.cpp') diff --git a/src/lua-interface.cpp b/src/lua-interface.cpp index f560bd3..e85eab1 100644 --- a/src/lua-interface.cpp +++ b/src/lua-interface.cpp @@ -91,6 +91,23 @@ extern void luacd_init(Lua * L) WEAK; #define LIGHT #endif +class pthreadlocker_t : public locker_t { + public: + pthreadlocker_t() { init_mutex(); } + ~pthreadlocker_t() { pthread_mutex_destroy(&mutex); } + virtual void lock() { pthread_mutex_lock(&mutex); } + virtual void unlock() { pthread_mutex_unlock(&mutex); } + private: + void init_mutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex, &attr); + pthread_mutexattr_destroy(&attr); + } + pthread_mutex_t mutex; +}; + #ifdef _WIN32 #include @@ -224,16 +241,23 @@ class threaded_Lua : public Lua { threaded_Lua(lua_State * __L) : Lua(__L) { init_mutex(); } - void init_mutex() { + static void init_mutex() { + if (did_init) + return; + did_init = true; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); pthread_mutexattr_destroy(&attr); } - pthread_mutex_t mutex; + static pthread_mutex_t mutex; + static bool did_init; }; +pthread_mutex_t threaded_Lua::mutex; +bool threaded_Lua::did_init = false; + class LuaStderrPrinter : public LuaPrinter { public: LuaStderrPrinter() { } @@ -261,6 +285,7 @@ enum baselua_interface_t { BASELUA_INTERFACE_PRELOAD, BASELUA_INTERFACE_LOADMODULE, BASELUA_INTERFACE_UNLINK, + BASELUA_INTERFACE_NEWTHREAD, }; struct lua_functypes_t baselua_interface_functions[] = { @@ -268,17 +293,25 @@ struct lua_functypes_t baselua_interface_functions[] = { { BASELUA_INTERFACE_PRELOAD, "preload", 0, 1, { BLUA_STRING | BLUA_OBJECT } }, { BASELUA_INTERFACE_LOADMODULE, "loadmodule", 1, 1, { BLUA_STRING } }, { BASELUA_INTERFACE_UNLINK, "unlink", 1, 1, { BLUA_STRING } }, + { BASELUA_INTERFACE_NEWTHREAD, "newthread", 1, 1, { BLUA_STRING } }, { -1, 0, 0, 0, 0 } }; +struct thread_info_t { + Lua * L; + char * execstr; +}; + class sLua_baselua_interface : public Base { public: DECLARE_FUNCTION(baselua_interface, BASELUA_INTERFACE_LOAD); DECLARE_FUNCTION(baselua_interface, BASELUA_INTERFACE_PRELOAD); DECLARE_FUNCTION(baselua_interface, BASELUA_INTERFACE_LOADMODULE); DECLARE_FUNCTION(baselua_interface, BASELUA_INTERFACE_UNLINK); + DECLARE_FUNCTION(baselua_interface, BASELUA_INTERFACE_NEWTHREAD); private: static int baselua_interface_proceed_statics(Lua * L, int n, int caller); + static void * spawn_thread(void *); }; void Luabaselua_interface::pushstatics(Lua * L) throw (GeneralException ) { @@ -288,12 +321,30 @@ void Luabaselua_interface::pushstatics(Lua * L) throw (GeneralException ) { PUSH_FUNCTION(baselua_interface, BASELUA_INTERFACE_PRELOAD); PUSH_FUNCTION(baselua_interface, BASELUA_INTERFACE_LOADMODULE); PUSH_FUNCTION(baselua_interface, BASELUA_INTERFACE_UNLINK); + PUSH_FUNCTION(baselua_interface, BASELUA_INTERFACE_NEWTHREAD); +} + +void * sLua_baselua_interface::spawn_thread(void * _ti) { + thread_info_t * ti = (thread_info_t *) _ti; + + try { + ti->L->load(ti->execstr, true); + } + catch (GeneralException e) { + printm(M_ERROR, "Got an exception during a thread: %s\n", e.GetMsg()); + } + + free(ti); + + return NULL; } int sLua_baselua_interface::baselua_interface_proceed_statics(Lua * L, int n, int caller) { int r = 0; String filename; const char * t; + thread_info_t * ti; + pthread_t pt; switch (caller) { case BASELUA_INTERFACE_LOAD: @@ -378,6 +429,15 @@ int sLua_baselua_interface::baselua_interface_proceed_statics(Lua * L, int n, in L->push((lua_Number) unlink(t)); r = 1; break; + case BASELUA_INTERFACE_NEWTHREAD: + ti = (thread_info_t *) malloc(sizeof(thread_info_t)); + ti->L = L->thread(); + ti->execstr = L->tostring(1).strdup(); + if (pthread_create(&pt, 0, sLua_baselua_interface::spawn_thread, ti)) { + L->error("Error creating thread"); + } + pthread_detach(pt); + break; } return r; } @@ -756,6 +816,8 @@ virtual int startup() throw (GeneralException) { String hport = "1500", tport = "1550", mport = "2500"; pthread_t interactive_thread; + locker = new pthreadlocker_t(); + verbosity = M_WARNING; showbanner(); -- cgit v1.2.3