diff options
| author | Pixel <pixel@nobis-crew.org> | 2009-10-05 16:54:34 -0700 | 
|---|---|---|
| committer | Pixel <pixel@nobis-crew.org> | 2009-10-05 16:54:34 -0700 | 
| commit | a41c6c12ba0a3db297ae945b0700d48e2d1905f8 (patch) | |
| tree | e8eeb8012a6496b0fc7c0c84edb0c102e9136e89 /src | |
| parent | 4a19ee400c7fe4fddaf1b99e63494f18a49fee2d (diff) | |
Adding the newthread() call for a fully pthreaded lua environment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lua-interface.cpp | 66 | 
1 files changed, 64 insertions, 2 deletions
| 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 <windows.h> @@ -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(); | 
