aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Thread/thread.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-08-07 23:29:28 +0800
committerchai <chaifix@163.com>2018-08-07 23:29:28 +0800
commitf5e30a91cfe12118d2c5d389687ebb931a196c7c (patch)
tree8d410f5c4fcf421d18ef0c95dd4b6a8b3e247a46 /src/libjin/Thread/thread.cpp
parent2576caf003fdb3162ab8a3c7bf77c38a885c3858 (diff)
*update
Diffstat (limited to 'src/libjin/Thread/thread.cpp')
-rw-r--r--src/libjin/Thread/thread.cpp309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp
new file mode 100644
index 0000000..064d3db
--- /dev/null
+++ b/src/libjin/Thread/thread.cpp
@@ -0,0 +1,309 @@
+#include "../modules.h"
+#if JIN_MODULES_THREAD
+
+#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(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);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ 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)
+ , 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(ThreadFunciton, 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(int slot, 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();
+ }
+
+} // thread
+} // jin
+
+#endif // JIN_MODULES_THREAD \ No newline at end of file