diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libjin/Thread/Thread.cpp | 67 | ||||
-rw-r--r-- | src/libjin/Thread/Thread.h | 129 | ||||
-rw-r--r-- | src/libjin/Utils/Proxy/lock.h | 4 | ||||
-rw-r--r-- | src/libjin/jin.h | 8 | ||||
-rw-r--r-- | src/libjin/thread/thread.cpp | 67 | ||||
-rw-r--r-- | src/libjin/thread/thread.h | 129 | ||||
-rw-r--r-- | src/lua/thread/luaopen_Thread.cpp | 50 | ||||
-rw-r--r-- | src/lua/thread/luaopen_thread.cpp | 182 |
8 files changed, 461 insertions, 175 deletions
diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/Thread.cpp index 06975f7..374778b 100644 --- a/src/libjin/Thread/Thread.cpp +++ b/src/libjin/Thread/Thread.cpp @@ -23,6 +23,7 @@ namespace thread friend class Conditional; }; + // ̼߳signal wait class Conditional { public: @@ -43,15 +44,19 @@ namespace thread Lock(Mutex* m) : mutex(m) { mutex->lock(); } + Lock(Mutex& m) : mutex(&m) { mutex->lock(); } + ~Lock() { mutex->unlock(); } private: Mutex* mutex; + Lock(Lock&) {} + }; ////////////////////////////////////////////////////////////////////// @@ -137,33 +142,43 @@ namespace thread { } - void Thread::ThreadData::set(std::string name, Value value) + void Thread::ThreadData::set(int slot, Variant value) { - //if (share.count(name) != 0); - share[name] = value; + Lock l(mutex); + share[slot] = value; } - Thread::Value Thread::ThreadData::get(std::string name) + Thread::Variant Thread::ThreadData::get(int slot) { - return share[name]; + Lock l(mutex); + return share[slot]; } - bool Thread::ThreadData::exist(const std::string& name) + bool Thread::ThreadData::exist(int slot) { - return share.count(name) == 1; + Lock l(mutex); + return share.count(slot) == 1; } - void Thread::ThreadData::remove(std::string name) + void Thread::ThreadData::remove(int slot) { Lock l(mutex); - if (exist(name)) + if (exist(slot)) { - share.erase(name); + share.erase(slot); } } ////////////////////////////////////////////////////////////////////// + int Thread::ThreadFunciton(void* p) + { + Thread* thread = (Thread*)p; + if (thread->threadRunner != nullptr) + thread->threadRunner(thread); + return 0; + } + Thread::Thread(const std::string tname, ThreadRunner runner) : name(tname) , running(false) @@ -204,7 +219,7 @@ namespace thread #endif } #if JIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), this); + handle = SDL_CreateThread(ThreadFunciton, name.c_str(), this); #elif JIN_THREAD_CPP handle = new std::thread(); #endif @@ -238,35 +253,45 @@ namespace thread mutex->unlock(); } - void Thread::send(std::string name, Value value) + void Thread::send(int slot, Variant value) { lock(); - common->set(name, value); + common->set(slot, value); unlock(); condition->broadcast(); } - bool Thread::receive(std::string name) + bool Thread::receive(int slot) { - return common->exist(name); + return common->exist(slot); } - Thread::Value Thread::fetch(std::string name) + Thread::Variant Thread::fetch(int slot) { - Thread::Value v = common->get(name); + Thread::Variant v = common->get(slot); return v; } - Thread::Value Thread::demand(std::string name) + Thread::Variant Thread::demand(int slot) { + /** + * pthread_mutex_lock(mtx); + * while(pass == 0) + * { + * pthread_mutex_unlock(mtx); + * pthread_cond_just_wait(cv); + * pthread_mutex_lock(mtx); + * } + * pthread_mutex_unlock(mtx); + */ lock(); - while (!common->exist(name)) + while (!common->exist(slot)) { - if (common->exist("error")) + if (common->exist(ThreadData::SLOT_ERROR)) return 0; condition->wait(mutex); } - Thread::Value v = common->get(name); + Thread::Variant v = common->get(slot); unlock(); return v; } diff --git a/src/libjin/Thread/Thread.h b/src/libjin/Thread/Thread.h index 4996705..aeb0d9e 100644 --- a/src/libjin/Thread/Thread.h +++ b/src/libjin/Thread/Thread.h @@ -17,54 +17,48 @@ namespace jin { namespace thread { - /* - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ + /** + * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ + * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ + * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz + * һӦûҪ˻ƵԴУꡢСжϴڶеĴ + * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ + * ߣָѣ + */ class Mutex; class Conditional; - /* - * Thread:demand Receive a message from a thread. Wait for the message to exist before returning. - * Thread:getName Get the name of a thread. - * Thread:kill Forcefully terminate the thread. - * Thread:peek Receive a message from a thread, but leave it in the message box. - * Thread:receive Receive a message from a thread. - * Thread:send Send a message. - * Thread:set Set a value. - * Thread:start Starts the thread. - * Thread:wait Wait for a thread to finish. - */ + /** + * Thread::demand Receive a message from a thread. Wait for the message to exist before returning. + * Thread::getName Get the name of a thread. + * Thread::kill Forcefully terminate the thread. + * Thread::peek Receive a message from a thread, but leave it in the message box. + * Thread::receive Receive a message from a thread. + * Thread::send Send a message. + * Thread::set Set a value. + * Thread::start Starts the thread. + * Thread::wait Wait for a thread to finish. + */ class Thread { public: - union Value + + union Variant { - enum - { - INTEGER, - REAL, - BOOL, - STRING, - POINTER - } type; - int integer; - float real; bool boolean; + char character; const char* cstring; void* pointer; + float real; - Value() {}; - Value(int i) : integer(i), type(INTEGER){}; - Value(float r) : real(r), type(REAL) {}; - Value(bool b) : boolean(b), type(BOOL) {}; - Value(const char* cstr) : cstring(cstr), type(STRING) {}; - Value(void* p) : pointer(p), type(POINTER) {}; + Variant() {}; + Variant(int i) : integer(i) {}; + Variant(float f) : real(f) {}; + Variant(bool b) : boolean(b) {}; + Variant(char c) : character(c) {}; + Variant(const char* s) : cstring(s) {}; + Variant(void* p) : pointer(p) {}; }; private: @@ -73,36 +67,36 @@ namespace thread public: ThreadData(Mutex*, Conditional*); ~ThreadData(); - bool exist(const std::string& name); - void set(std::string name, Value value); - Value get(std::string name); - void remove(std::string name); + bool exist(int slot); + void set(int slot, Variant value); + Variant get(int slot); + void remove(int slot); Conditional* condition; Mutex* mutex; + static const int SLOT_ERROR = -1; + static const int SLOT_WARN = -2; + private: - std::map<std::string, Value> share; // threads shared value - std::map<std::string, void*> sharevalue; + std::map<int, Variant> share; // threads shared value }; public: - typedef int(ThreadRunner)(void* /*ThreadData*/); + typedef void(ThreadRunner)(Thread* thread); Thread(const std::string name, ThreadRunner threadfuncs); ~Thread(); bool start(); void wait(); - void send(std::string name, Value value); - bool receive(std::string name); - Value fetch(std::string name); - Value demand(std::string name); + void send(int slot, Variant value); + bool receive(int slot); + Variant fetch(int slot); + Variant demand(int slot); const char* getName(); bool isRunning(); - //void kill(); - //Value peek(); - - private: void lock(); void unlock(); + + private: #if JIN_THREAD_SDL SDL_Thread* handle; // SDL thread #elif JIN_THREAD_CPP @@ -112,9 +106,40 @@ namespace thread Conditional* condition; // condition variable ThreadRunner* threadRunner; // thread function ThreadData* common; // threads common data - const std::string name; // thread name + const std::string name; // thread name, for debugging purposes + /** + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * Use short names because they don't make the lines in a log file too long. + * + * Create names where the important part is at the beginning. Log viewers in a + * graphical user interface tend to have tables with columns, and the thread + * column is usually small or will be made small by you to read everything else. + * + * Do not use the word "thread" in the thread name because it is obvious. + * + * Make the thread names easily grep-able. Avoid similar sounding thread names + * + * If you have several threads of the same nature, enumerate them with IDs that + * are unique to one execution of the application or one log file, whichever fits + * your logging habits. + * + * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker + * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or + * "Calculation" (what does it calculate?). + * + * If you have a test group that uses thread names to grep your application's log + * files, do not rename your threads after some time. Your testers will hate you for + * doing so. Thread names in well-tested applications should be there to stay. + * + * When you have threads that service a network connection, try to include the target + * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about + * enumeration though if there are multiple connections to the same host. + */ bool running; // running + static int ThreadFunciton(void* p); + }; } // thread diff --git a/src/libjin/Utils/Proxy/lock.h b/src/libjin/Utils/Proxy/lock.h new file mode 100644 index 0000000..29194a1 --- /dev/null +++ b/src/libjin/Utils/Proxy/lock.h @@ -0,0 +1,4 @@ +class Lock +{ + +};
\ No newline at end of file diff --git a/src/libjin/jin.h b/src/libjin/jin.h index 148911c..ad83fae 100644 --- a/src/libjin/jin.h +++ b/src/libjin/jin.h @@ -15,9 +15,9 @@ #include "Time/Timer.h" #include "Thread/Thread.h" -#define JIN_VERSION "Jin 0.1" -#define JIN_AUTHOR "Chai" -#define JIN_RELEASE "Jin 0.1.1" -#define JIN_VERSION_NUM 101; +const char* JIN_VERSION = "Jin 0.1"; +const char* JIN_AUTHOR = "Chai"; +const char* JIN_RELEASE = "Jin 0.1.1"; +const int JIN_VERSION_NUM = 101; #endif // __JIN_H
\ No newline at end of file diff --git a/src/libjin/thread/thread.cpp b/src/libjin/thread/thread.cpp index 06975f7..374778b 100644 --- a/src/libjin/thread/thread.cpp +++ b/src/libjin/thread/thread.cpp @@ -23,6 +23,7 @@ namespace thread friend class Conditional; }; + // ̼߳signal wait class Conditional { public: @@ -43,15 +44,19 @@ namespace thread Lock(Mutex* m) : mutex(m) { mutex->lock(); } + Lock(Mutex& m) : mutex(&m) { mutex->lock(); } + ~Lock() { mutex->unlock(); } private: Mutex* mutex; + Lock(Lock&) {} + }; ////////////////////////////////////////////////////////////////////// @@ -137,33 +142,43 @@ namespace thread { } - void Thread::ThreadData::set(std::string name, Value value) + void Thread::ThreadData::set(int slot, Variant value) { - //if (share.count(name) != 0); - share[name] = value; + Lock l(mutex); + share[slot] = value; } - Thread::Value Thread::ThreadData::get(std::string name) + Thread::Variant Thread::ThreadData::get(int slot) { - return share[name]; + Lock l(mutex); + return share[slot]; } - bool Thread::ThreadData::exist(const std::string& name) + bool Thread::ThreadData::exist(int slot) { - return share.count(name) == 1; + Lock l(mutex); + return share.count(slot) == 1; } - void Thread::ThreadData::remove(std::string name) + void Thread::ThreadData::remove(int slot) { Lock l(mutex); - if (exist(name)) + if (exist(slot)) { - share.erase(name); + share.erase(slot); } } ////////////////////////////////////////////////////////////////////// + int Thread::ThreadFunciton(void* p) + { + Thread* thread = (Thread*)p; + if (thread->threadRunner != nullptr) + thread->threadRunner(thread); + return 0; + } + Thread::Thread(const std::string tname, ThreadRunner runner) : name(tname) , running(false) @@ -204,7 +219,7 @@ namespace thread #endif } #if JIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), this); + handle = SDL_CreateThread(ThreadFunciton, name.c_str(), this); #elif JIN_THREAD_CPP handle = new std::thread(); #endif @@ -238,35 +253,45 @@ namespace thread mutex->unlock(); } - void Thread::send(std::string name, Value value) + void Thread::send(int slot, Variant value) { lock(); - common->set(name, value); + common->set(slot, value); unlock(); condition->broadcast(); } - bool Thread::receive(std::string name) + bool Thread::receive(int slot) { - return common->exist(name); + return common->exist(slot); } - Thread::Value Thread::fetch(std::string name) + Thread::Variant Thread::fetch(int slot) { - Thread::Value v = common->get(name); + Thread::Variant v = common->get(slot); return v; } - Thread::Value Thread::demand(std::string name) + Thread::Variant Thread::demand(int slot) { + /** + * pthread_mutex_lock(mtx); + * while(pass == 0) + * { + * pthread_mutex_unlock(mtx); + * pthread_cond_just_wait(cv); + * pthread_mutex_lock(mtx); + * } + * pthread_mutex_unlock(mtx); + */ lock(); - while (!common->exist(name)) + while (!common->exist(slot)) { - if (common->exist("error")) + if (common->exist(ThreadData::SLOT_ERROR)) return 0; condition->wait(mutex); } - Thread::Value v = common->get(name); + Thread::Variant v = common->get(slot); unlock(); return v; } diff --git a/src/libjin/thread/thread.h b/src/libjin/thread/thread.h index 4996705..aeb0d9e 100644 --- a/src/libjin/thread/thread.h +++ b/src/libjin/thread/thread.h @@ -17,54 +17,48 @@ namespace jin { namespace thread { - /* - * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ - * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ - * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz - * һӦûҪ˻ƵԴУꡢСжϴڶеĴ - * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ - * ߣָѣ - */ + /** + * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ + * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ + * ָһԹԴзʵĴ룬һֻƻ㷨һ̡߳̿ӵжٽDz + * һӦûҪ˻ƵԴУꡢСжϴڶеĴ + * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ + * ߣָѣ + */ class Mutex; class Conditional; - /* - * Thread:demand Receive a message from a thread. Wait for the message to exist before returning. - * Thread:getName Get the name of a thread. - * Thread:kill Forcefully terminate the thread. - * Thread:peek Receive a message from a thread, but leave it in the message box. - * Thread:receive Receive a message from a thread. - * Thread:send Send a message. - * Thread:set Set a value. - * Thread:start Starts the thread. - * Thread:wait Wait for a thread to finish. - */ + /** + * Thread::demand Receive a message from a thread. Wait for the message to exist before returning. + * Thread::getName Get the name of a thread. + * Thread::kill Forcefully terminate the thread. + * Thread::peek Receive a message from a thread, but leave it in the message box. + * Thread::receive Receive a message from a thread. + * Thread::send Send a message. + * Thread::set Set a value. + * Thread::start Starts the thread. + * Thread::wait Wait for a thread to finish. + */ class Thread { public: - union Value + + union Variant { - enum - { - INTEGER, - REAL, - BOOL, - STRING, - POINTER - } type; - int integer; - float real; bool boolean; + char character; const char* cstring; void* pointer; + float real; - Value() {}; - Value(int i) : integer(i), type(INTEGER){}; - Value(float r) : real(r), type(REAL) {}; - Value(bool b) : boolean(b), type(BOOL) {}; - Value(const char* cstr) : cstring(cstr), type(STRING) {}; - Value(void* p) : pointer(p), type(POINTER) {}; + Variant() {}; + Variant(int i) : integer(i) {}; + Variant(float f) : real(f) {}; + Variant(bool b) : boolean(b) {}; + Variant(char c) : character(c) {}; + Variant(const char* s) : cstring(s) {}; + Variant(void* p) : pointer(p) {}; }; private: @@ -73,36 +67,36 @@ namespace thread public: ThreadData(Mutex*, Conditional*); ~ThreadData(); - bool exist(const std::string& name); - void set(std::string name, Value value); - Value get(std::string name); - void remove(std::string name); + bool exist(int slot); + void set(int slot, Variant value); + Variant get(int slot); + void remove(int slot); Conditional* condition; Mutex* mutex; + static const int SLOT_ERROR = -1; + static const int SLOT_WARN = -2; + private: - std::map<std::string, Value> share; // threads shared value - std::map<std::string, void*> sharevalue; + std::map<int, Variant> share; // threads shared value }; public: - typedef int(ThreadRunner)(void* /*ThreadData*/); + typedef void(ThreadRunner)(Thread* thread); Thread(const std::string name, ThreadRunner threadfuncs); ~Thread(); bool start(); void wait(); - void send(std::string name, Value value); - bool receive(std::string name); - Value fetch(std::string name); - Value demand(std::string name); + void send(int slot, Variant value); + bool receive(int slot); + Variant fetch(int slot); + Variant demand(int slot); const char* getName(); bool isRunning(); - //void kill(); - //Value peek(); - - private: void lock(); void unlock(); + + private: #if JIN_THREAD_SDL SDL_Thread* handle; // SDL thread #elif JIN_THREAD_CPP @@ -112,9 +106,40 @@ namespace thread Conditional* condition; // condition variable ThreadRunner* threadRunner; // thread function ThreadData* common; // threads common data - const std::string name; // thread name + const std::string name; // thread name, for debugging purposes + /** + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * Use short names because they don't make the lines in a log file too long. + * + * Create names where the important part is at the beginning. Log viewers in a + * graphical user interface tend to have tables with columns, and the thread + * column is usually small or will be made small by you to read everything else. + * + * Do not use the word "thread" in the thread name because it is obvious. + * + * Make the thread names easily grep-able. Avoid similar sounding thread names + * + * If you have several threads of the same nature, enumerate them with IDs that + * are unique to one execution of the application or one log file, whichever fits + * your logging habits. + * + * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker + * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or + * "Calculation" (what does it calculate?). + * + * If you have a test group that uses thread names to grep your application's log + * files, do not rename your threads after some time. Your testers will hate you for + * doing so. Thread names in well-tested applications should be there to stay. + * + * When you have threads that service a network connection, try to include the target + * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about + * enumeration though if there are multiple connections to the same host. + */ bool running; // running + static int ThreadFunciton(void* p); + }; } // thread diff --git a/src/lua/thread/luaopen_Thread.cpp b/src/lua/thread/luaopen_Thread.cpp index c08c262..99ddee1 100644 --- a/src/lua/thread/luaopen_Thread.cpp +++ b/src/lua/thread/luaopen_Thread.cpp @@ -32,9 +32,9 @@ namespace jin return nullptr; } - static int threadRunner(void* p) + static void threadRunner(jin::thread::Thread* t) { - Thread* thread = (Thread*)p; + Thread* thread = (Thread*)t; lua_State* L = lua_open(); luax_openlibs(L); luaopen_jin(L); @@ -64,21 +64,21 @@ namespace jin static int l_send(lua_State* L) { Thread* t = checkThread(L); - const char* name = luax_checkstring(L, 2); + int slot = luax_checkinteger(L, 2); if (luax_isnumber(L, 3)) { float real = luax_checknumber(L, 3); - t->send(name, real); + t->send(slot, real); } else if (luax_isboolean(L, 3)) { bool bol = luax_checkbool(L, 3); - t->send(name, bol); + t->send(slot, bol); } else if (luax_isstring(L, 3)) { const char* str = luax_checkstring(L, 3); - t->send(name, str); + t->send(slot, str); } return 0; } @@ -86,8 +86,8 @@ namespace jin static int l_receive(lua_State* L) { Thread* t = checkThread(L); - const char* name = luax_checkstring(L, 2); - bool result = t->receive(name); + int slot = luax_checkinteger(L, 2); + bool result = t->receive(slot); luax_pushboolean(L, result); return 1; } @@ -95,23 +95,23 @@ namespace jin static int l_fetch(lua_State* L) { Thread* t = checkThread(L); - const char* name = luax_checkstring(L, 2); - Thread::Value v = t->fetch(name); - if (v.type == Thread::Value::INTEGER) - { - luax_pushinteger(L, v.integer); - } - else if (v.type == Thread::Value::BOOL) - { - luax_pushboolean(L, v.boolean); - } - else if (v.type == Thread::Value::STRING) - { - luax_pushstring(L, v.cstring); - } - else if (v.type == Thread::Value::POINTER) - { - } + int slot = luax_checkinteger(L, 2); + Thread::Variant v = t->fetch(slot); + //if (v.type == Thread::Value::INTEGER) + //{ + // luax_pushinteger(L, v.integer); + //} + //else if (v.type == Thread::Value::BOOL) + //{ + // luax_pushboolean(L, v.boolean); + //} + //else if (v.type == Thread::Value::STRING) + //{ + // luax_pushstring(L, v.cstring); + //} + //else if (v.type == Thread::Value::POINTER) + //{ + //} return 1; } diff --git a/src/lua/thread/luaopen_thread.cpp b/src/lua/thread/luaopen_thread.cpp new file mode 100644 index 0000000..99ddee1 --- /dev/null +++ b/src/lua/thread/luaopen_thread.cpp @@ -0,0 +1,182 @@ +#include "lua/luax.h" +#include "libjin/jin.h" +#include "../luaopen_jin.h" +#include "../luaopen_types.h" + +namespace jin +{ + namespace lua + { + + static int luaopen_thread(lua_State* L); + + class Thread : public jin::thread::Thread + { + public: + Thread(std::string _name, std::string _code, jin::thread::Thread::ThreadRunner runner) + : jin::thread::Thread(name, runner) + , name(_name) + , code(_code) + { + } + + const std::string name; + const std::string code; + }; + + static inline Thread* checkThread(lua_State* L) + { + Proxy* proxy = (Proxy*)luax_checktype(L, 1, TYPE_THREAD); + if (proxy != nullptr) + return (Thread*)proxy->object; + return nullptr; + } + + static void threadRunner(jin::thread::Thread* t) + { + Thread* thread = (Thread*)t; + lua_State* L = lua_open(); + luax_openlibs(L); + luaopen_jin(L); + luax_dostring(L, thread->code.c_str()); + } + + static int l_gc(lua_State* L) + { + return 1; + } + + static int l_start(lua_State* L) + { + Thread* t = checkThread(L); + bool result = t->start(); + luax_pushboolean(L, result); + return 1; + } + + static int l_wait(lua_State* L) + { + Thread* t = checkThread(L); + t->wait(); + return 0; + } + + static int l_send(lua_State* L) + { + Thread* t = checkThread(L); + int slot = luax_checkinteger(L, 2); + if (luax_isnumber(L, 3)) + { + float real = luax_checknumber(L, 3); + t->send(slot, real); + } + else if (luax_isboolean(L, 3)) + { + bool bol = luax_checkbool(L, 3); + t->send(slot, bol); + } + else if (luax_isstring(L, 3)) + { + const char* str = luax_checkstring(L, 3); + t->send(slot, str); + } + return 0; + } + + static int l_receive(lua_State* L) + { + Thread* t = checkThread(L); + int slot = luax_checkinteger(L, 2); + bool result = t->receive(slot); + luax_pushboolean(L, result); + return 1; + } + + static int l_fetch(lua_State* L) + { + Thread* t = checkThread(L); + int slot = luax_checkinteger(L, 2); + Thread::Variant v = t->fetch(slot); + //if (v.type == Thread::Value::INTEGER) + //{ + // luax_pushinteger(L, v.integer); + //} + //else if (v.type == Thread::Value::BOOL) + //{ + // luax_pushboolean(L, v.boolean); + //} + //else if (v.type == Thread::Value::STRING) + //{ + // luax_pushstring(L, v.cstring); + //} + //else if (v.type == Thread::Value::POINTER) + //{ + //} + return 1; + } + + static int l_demand(lua_State* L) + { + Thread* t = checkThread(L); + + return 1; + } + + static int l_getName(lua_State* L) + { + return 1; + } + + static int l_isRunning(lua_State* L) + { + return 1; + } + + static const luaL_Reg thread_function[] = { + { "__gc", l_gc }, + { "start", l_start }, + { "wait", l_wait }, + { "send", l_send }, + { "receive", l_receive }, + { "fetch", l_fetch }, + { "demand", l_demand }, + { "getName", l_getName }, + { "isRunning", l_isRunning }, + { 0, 0 } + }; + + static int luaopen_Thread(lua_State* L) + { + luax_newtype(L, TYPE_SOURCE, thread_function); + + return 0; + } + + // jin.thread.Thread(name) + static int l_newThread(lua_State* L) + { + const char* name = luax_checkstring(L, 1); + const char* code = luax_checkstring(L, 2); + Proxy* proxy = (Proxy*)luax_newinstance(L, TYPE_THREAD, sizeof(Proxy)); + Thread* thread = new Thread(name, code, threadRunner); + proxy->bind(thread); + return 1; + } + + static int l_getThread(lua_State* L) + { + + } + + static const luaL_Reg f[] = { + { "Thread", l_newThread}, + { "getThread", l_getThread}, + { 0, 0 } + }; + + static int luaopen_thread(lua_State* L) + { + + } + } +}
\ No newline at end of file |