diff options
Diffstat (limited to 'src/libjin/Thread')
-rw-r--r-- | src/libjin/Thread/je_thread.cpp (renamed from src/libjin/Thread/Thread.cpp) | 4 | ||||
-rw-r--r-- | src/libjin/Thread/je_thread.h (renamed from src/libjin/Thread/Thread.h) | 10 | ||||
-rw-r--r-- | src/libjin/Thread/thread.cpp | 301 | ||||
-rw-r--r-- | src/libjin/Thread/thread.h | 166 |
4 files changed, 7 insertions, 474 deletions
diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/je_thread.cpp index 3f2a50d..6bf6f46 100644 --- a/src/libjin/Thread/Thread.cpp +++ b/src/libjin/Thread/je_thread.cpp @@ -1,7 +1,7 @@ -#include "../configuration.h" +#include "../core/je_configuration.h" #if LIBJIN_MODULES_THREAD -#include "Thread.h" +#include "je_thread.h" namespace jin { diff --git a/src/libjin/Thread/Thread.h b/src/libjin/Thread/je_thread.h index ea50444..bdbc093 100644 --- a/src/libjin/Thread/Thread.h +++ b/src/libjin/Thread/je_thread.h @@ -1,16 +1,16 @@ #ifndef __LIBJIN_THREAD_H #define __LIBJIN_THREAD_H -#include "../configuration.h" +#include "../core/je_configuration.h" #if LIBJIN_MODULES_THREAD #include <string> #include <map> #if LIBJIN_THREAD_SDL -# include "SDL2/SDL_thread.h" + #include "SDL2/SDL_thread.h" #elif LIBJIN_THREAD_CPP -# include <thread> -# include <mutex> -# include <condition_variable> + #include <thread> + #include <mutex> + #include <condition_variable> #endif namespace jin diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp deleted file mode 100644 index 3f2a50d..0000000 --- a/src/libjin/Thread/thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include "Thread.h" - -namespace jin -{ - namespace thread - { - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if LIBJIN_THREAD_SDL - SDL_mutex* mutex; - #endif - friend class Conditional; - }; - - // ̼߳signal wait - class Conditional - { - public: - Conditional(); - ~Conditional(); - void signal(); - void broadcast(); - bool wait(Mutex* mutex, int timeout = -1); - private: - #if LIBJIN_THREAD_SDL - SDL_cond* cond; - #endif - }; - - class Lock - { - public: - Lock(Mutex* m) : mutex(m) { - mutex->lock(); - } - - Lock(Mutex& m) : mutex(&m) { - mutex->lock(); - } - - ~Lock() { - mutex->unlock(); - } - private: - Mutex* mutex; - - Lock(Lock&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - Mutex::Mutex() - { - #if LIBJIN_THREAD_SDL - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if LIBJIN_THREAD_SDL - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if LIBJIN_THREAD_SDL - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if LIBJIN_THREAD_SDL - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if LIBJIN_THREAD_SDL - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if LIBJIN_THREAD_SDL - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if LIBJIN_THREAD_SDL - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if LIBJIN_THREAD_SDL - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if LIBJIN_THREAD_SDL - if (timeout < 0) - return !SDL_CondWait(cond, mutex->mutex); - else - return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Thread::ThreadData::ThreadData(Mutex* m, Conditional* c) - : mutex(m) - , condition(c) - , share() - { - } - - Thread::ThreadData::~ThreadData() - { - } - - void Thread::ThreadData::set(int slot, Variant value) - { - Lock l(mutex); - share[slot] = value; - } - - Thread::Variant Thread::ThreadData::get(int slot) - { - Lock l(mutex); - return share[slot]; - } - - bool Thread::ThreadData::exist(int slot) - { - Lock l(mutex); - return share.count(slot) == 1; - } - - void Thread::ThreadData::remove(int slot) - { - Lock l(mutex); - if (exist(slot)) - { - share.erase(slot); - } - } - - ////////////////////////////////////////////////////////////////////// - - Thread::Thread(const std::string tname, ThreadRunner runner) - : name(tname) - , running(false) - , threadRunner(runner) - { - mutex = new Mutex(); - condition = new Conditional(); - common = new Thread::ThreadData(mutex, condition); - } - - Thread::~Thread() - { - #if LIBJIN_THREAD_SDL - #endif - } - - const char* Thread::getName() - { - Lock l(mutex); - return name.c_str(); - }; - - bool Thread::isRunning() - { - Lock l(mutex); - return running; - }; - - bool Thread::start(void* p) - { - Lock l(mutex); - if (running) - return false; - if (handle) - { - #if LIBJIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - } - #if LIBJIN_THREAD_SDL - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif LIBJIN_THREAD_CPP - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if LIBJIN_THREAD_SDL - SDL_WaitThread(handle, nullptr); - #endif - Lock l(mutex); - running = false; - handle = nullptr; - } - - void Thread::lock() - { - if (mutex != nullptr) - mutex->lock(); - } - - void Thread::unlock() - { - if (mutex != nullptr) - mutex->unlock(); - } - - void Thread::send(int slot, const Variant& value) - { - lock(); - common->set(slot, value); - unlock(); - condition->broadcast(); - } - - bool Thread::receive(int slot) - { - return common->exist(slot); - } - - Thread::Variant Thread::fetch(int slot) - { - Thread::Variant v = common->get(slot); - return v; - } - - 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(slot)) - { - if (common->exist(ThreadData::SLOT_ERROR)) - return 0; - condition->wait(mutex); - } - Thread::Variant v = common->get(slot); - unlock(); - return v; - } - - void Thread::remove(int slot) - { - lock(); - common->remove(slot); - unlock(); - } - - } // namespace thread -} // namespace jin - -#endif // LIBJIN_MODULES_THREAD
\ No newline at end of file diff --git a/src/libjin/Thread/thread.h b/src/libjin/Thread/thread.h deleted file mode 100644 index ea50444..0000000 --- a/src/libjin/Thread/thread.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __LIBJIN_THREAD_H -#define __LIBJIN_THREAD_H -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include <string> -#include <map> -#if LIBJIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif LIBJIN_THREAD_CPP -# include <thread> -# include <mutex> -# include <condition_variable> -#endif - -namespace jin -{ - namespace thread - { - /** - * ӢӢ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. - */ - class Thread - { - public: - struct Variant - { - enum Type - { - NONE = 0, - INTERGER, - BOOLEAN, - CHARACTER, - CSTRING, - POINTER, - REAL, - }; - Type type; - union - { - int integer; - bool boolean; - char character; - const char* cstring; - void* pointer; - float real; - }; - Variant() :type(NONE) {}; - Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); } - Variant(int i) : integer(i), type(INTERGER) {}; - Variant(float f) : real(f), type(REAL) {}; - Variant(bool b) : boolean(b), type(BOOLEAN) {}; - Variant(char c) : character(c), type(CHARACTER) {}; - Variant(const char* s) : cstring(s), type(CSTRING) {}; - Variant(void* p) : pointer(p), type(POINTER) {}; - }; - - private: - class ThreadData - { - public: - static const int SLOT_ERROR = -1; - static const int SLOT_WARN = -2; - static const int SLOT_INFO = -3; - static const int SLOT_DEBUG = -4; - - ThreadData(Mutex*, Conditional*); - ~ThreadData(); - bool exist(int slot); - void set(int slot, Variant value); - Variant get(int slot); - void remove(int slot); - - Conditional* condition; - Mutex* mutex; - - private: - std::map<int, Variant> share; // threads shared value - - }; - - public: - typedef int(*ThreadRunner)(void* obj); - - Thread(const std::string name, ThreadRunner threadfuncs); - ~Thread(); - bool start(void* p); - void wait(); - void send(int slot, const Variant& value); - bool receive(int slot); - Variant fetch(int slot); - Variant demand(int slot); - void remove(int slot); - const char* getName(); - bool isRunning(); - void lock(); - void unlock(); - - protected: - #if LIBJIN_THREAD_SDL - SDL_Thread* handle; // SDL thread - #elif LIBJIN_THREAD_CPP - std::thread* handle; // cpp thread - #endif - Mutex* mutex; // mutex variable - Conditional* condition; // condition variable - ThreadRunner threadRunner; // thread function - ThreadData* common; // threads common data - 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 - - }; - - } // namespace thread -} // namespace jin - -#endif // LIBJIN_MODULES_THREAD -#endif // __LIBJIN_THREAD_H
\ No newline at end of file |