diff options
author | chai <chaifix@163.com> | 2018-11-16 00:24:51 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-11-16 00:24:51 +0800 |
commit | 831e814ce9bdb84e86c06c4a52008f6bdaaa00d6 (patch) | |
tree | f91fccc7d2628d6e0a39886134b2bb174f5eede4 /src/libjin/multithread | |
parent | 6dc75930fe5fe02f1af5489917752d315cf9e48f (diff) |
*合并master到minimal分支
Diffstat (limited to 'src/libjin/multithread')
-rw-r--r-- | src/libjin/multithread/je_thread.cpp | 301 | ||||
-rw-r--r-- | src/libjin/multithread/je_thread.h | 167 |
2 files changed, 0 insertions, 468 deletions
diff --git a/src/libjin/multithread/je_thread.cpp b/src/libjin/multithread/je_thread.cpp deleted file mode 100644 index 0c528bf..0000000 --- a/src/libjin/multithread/je_thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../core/je_configuration.h" -#if defined(jin_thread) - -#include "je_thread.h" - -namespace JinEngine -{ - namespace MultiThread - { - - class Mutex - { - public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - private: - #if jin_thread == jin_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 jin_thread == jin_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 jin_thread == jin_thread_sdl - mutex = SDL_CreateMutex(); - #endif - } - - Mutex::~Mutex() - { - #if jin_thread == jin_thread_sdl - SDL_DestroyMutex(mutex); - #endif - } - - void Mutex::lock() - { - #if jin_thread == jin_thread_sdl - SDL_LockMutex(mutex); - #endif - } - - void Mutex::unlock() - { - #if jin_thread == jin_thread_sdl - SDL_UnlockMutex(mutex); - #endif - } - - ////////////////////////////////////////////////////////////////////// - - Conditional::Conditional() - { - #if jin_thread == jin_thread_sdl - cond = SDL_CreateCond(); - #endif - } - - Conditional::~Conditional() - { - #if jin_thread == jin_thread_sdl - SDL_DestroyCond(cond); - #endif - } - - void Conditional::signal() - { - #if jin_thread == jin_thread_sdl - SDL_CondSignal(cond); - #endif - } - - void Conditional::broadcast() - { - #if jin_thread == jin_thread_sdl - SDL_CondBroadcast(cond); - #endif - } - - bool Conditional::wait(Mutex* mutex, int timeout) - { - #if jin_thread == jin_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 jin_thread == jin_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 jin_thread == jin_thread_sdl - SDL_WaitThread(handle, nullptr); - #endif - } - #if jin_thread == jin_thread_sdl - handle = SDL_CreateThread(threadRunner, name.c_str(), p); - #elif jin_thread == jin_thread_cpp - handle = new std::thread(); - #endif - return (running = (handle != nullptr)); - } - - void Thread::wait() - { - { - Lock l(mutex); - if (!handle) - return; - } - #if jin_thread == jin_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 MultiThread -} // namespace JinEngine - -#endif // defined(jin_thread)
\ No newline at end of file diff --git a/src/libjin/multithread/je_thread.h b/src/libjin/multithread/je_thread.h deleted file mode 100644 index 353690c..0000000 --- a/src/libjin/multithread/je_thread.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef __JE_THREAD_H -#define __JE_THREAD_H -#include "../core/je_configuration.h" -#if defined(jin_thread) - -#include <string> -#include <map> -#if jin_thread == jin_thread_sdl - #include "SDL2/SDL_thread.h" -#elif jin_thread == jin_thread_cpp - #include <thread> - #include <mutex> - #include <condition_variable> -#endif - -namespace JinEngine -{ - namespace MultiThread - { - /** - * ӢӢ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 jin_thread == jin_thread_sdl - SDL_Thread* handle; // SDL thread - #elif jin_thread == jin_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 MultiThread -} // namespace JinEngine - -#endif // defined(jin_thread) - -#endif // __JE_THREAD_H
\ No newline at end of file |