diff options
Diffstat (limited to 'src/libjin/Thread/Thread.cpp')
-rw-r--r-- | src/libjin/Thread/Thread.cpp | 274 |
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 |