diff options
author | chai <chaifix@163.com> | 2019-01-12 21:48:33 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-01-12 21:48:33 +0800 |
commit | 8b00d67febf133e89f6a0bfabc41feed555dc4a9 (patch) | |
tree | fe48ef17c250afa40c2588300fcdb5920dba6951 /src/libjin/threads/thread.cpp | |
parent | a907c39756ef6b368d06643afa491c49a9044a8e (diff) |
*去掉文件前缀je_
Diffstat (limited to 'src/libjin/threads/thread.cpp')
-rw-r--r-- | src/libjin/threads/thread.cpp | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/src/libjin/threads/thread.cpp b/src/libjin/threads/thread.cpp new file mode 100644 index 0000000..1c35efb --- /dev/null +++ b/src/libjin/threads/thread.cpp @@ -0,0 +1,301 @@ +#include "../core/configuration.h" +#if defined(jin_thread) + +#include "thread.h" + +namespace JinEngine +{ + namespace Threads + { + + 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 Threads +} // namespace JinEngine + +#endif // defined(jin_thread)
\ No newline at end of file |