aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/thread/thread.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-08-06 16:22:00 +0800
committerchai <chaifix@163.com>2018-08-06 16:22:00 +0800
commit89e7a9ecfad9a54633eb3ebbab1d1f13ad78826f (patch)
tree1ba8a806af1b8e7750d6b637c296f08e13cf268e /src/libjin/thread/thread.cpp
parentea9769944a2db3abe15f537dab67e16fdfc20bef (diff)
*update
Diffstat (limited to 'src/libjin/thread/thread.cpp')
-rw-r--r--src/libjin/thread/thread.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/src/libjin/thread/thread.cpp b/src/libjin/thread/thread.cpp
index a874b0d..ae6498d 100644
--- a/src/libjin/thread/thread.cpp
+++ b/src/libjin/thread/thread.cpp
@@ -3,6 +3,280 @@
#include "Thread.h"
+namespace jin
+{
+namespace thread
+{
+ class Mutex
+ {
+ public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+ private:
+ #if 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_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_SDL
+ mutex = SDL_CreateMutex();
+ #endif
+ }
+
+ Mutex::~Mutex()
+ {
+ #if JIN_THREAD_SDL
+ SDL_DestroyMutex(mutex);
+ #endif
+ }
+
+ void Mutex::lock()
+ {
+ #if JIN_THREAD_SDL
+ SDL_LockMutex(mutex);
+ #endif
+ }
+
+ void Mutex::unlock()
+ {
+ #if JIN_THREAD_SDL
+ SDL_UnlockMutex(mutex);
+ #endif
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Conditional::Conditional()
+ {
+ #if JIN_THREAD_SDL
+ cond = SDL_CreateCond();
+ #endif
+ }
+
+ Conditional::~Conditional()
+ {
+ #if JIN_THREAD_SDL
+ SDL_DestroyCond(cond);
+ #endif
+ }
+
+ void Conditional::signal()
+ {
+ #if JIN_THREAD_SDL
+ SDL_CondSignal(cond);
+ #endif
+ }
+
+ void Conditional::broadcast()
+ {
+ #if JIN_THREAD_SDL
+ SDL_CondBroadcast(cond);
+ #endif
+ }
+
+ bool Conditional::wait(Mutex* mutex, int timeout)
+ {
+ #if 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(std::string name, Value value)
+ {
+ //if (share.count(name) != 0);
+ share[name] = value;
+ }
+
+ Thread::Value Thread::ThreadData::get(std::string name)
+ {
+ return share[name];
+ }
+
+ bool Thread::ThreadData::exist(const std::string& name)
+ {
+ return share.count(name) == 1;
+ }
+
+ void Thread::ThreadData::remove(std::string name)
+ {
+ Lock l(mutex);
+ if (exist(name))
+ {
+ share.erase(name);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ 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_SDL
+ #endif
+ }
+
+ const char* Thread::getName()
+ {
+ Lock l(mutex);
+ return name.c_str();
+ };
+
+ bool Thread::isRunning()
+ {
+ Lock l(mutex);
+ return running;
+ };
+
+ bool Thread::start()
+ {
+ Lock l(mutex);
+ if (running)
+ return false;
+ if (handle)
+ {
+ #if JIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ }
+ #if JIN_THREAD_SDL
+ handle = SDL_CreateThread(threadRunner, name.c_str(), this);
+ #elif JIN_THREAD_CPP
+ handle = new std::thread();
+ #endif
+ return (running = (handle != nullptr));
+ }
+
+ void Thread::wait()
+ {
+ {
+ Lock l(mutex);
+ if (!handle)
+ return;
+ }
+ #if 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(std::string name, Value value)
+ {
+ lock();
+ common->set(name, value);
+ unlock();
+ condition->broadcast();
+ }
+
+ bool Thread::receive(std::string name)
+ {
+ return common->exist(name);
+ }
+
+ Thread::Value Thread::fetch(std::string name)
+ {
+ Thread::Value v = common->get(name);
+ return v;
+ }
+
+ Thread::Value Thread::demand(std::string name)
+ {
+ lock();
+ while (!common->exist(name))
+ {
+ if (common->exist("error"))
+ return 0;
+ condition->wait(mutex);
+ }
+ Thread::Value v = common->get(name);
+ unlock();
+ return v;
+ }
+
+} // thread
+} // jin
#endif // JIN_MODULES_THREAD \ No newline at end of file