aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/Thread')
-rw-r--r--src/libjin/Thread/je_thread.cpp (renamed from src/libjin/Thread/Thread.cpp)4
-rw-r--r--src/libjin/Thread/je_thread.h (renamed from src/libjin/Thread/Thread.h)10
-rw-r--r--src/libjin/Thread/thread.cpp301
-rw-r--r--src/libjin/Thread/thread.h166
4 files changed, 7 insertions, 474 deletions
diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/je_thread.cpp
index 3f2a50d..6bf6f46 100644
--- a/src/libjin/Thread/Thread.cpp
+++ b/src/libjin/Thread/je_thread.cpp
@@ -1,7 +1,7 @@
-#include "../configuration.h"
+#include "../core/je_configuration.h"
#if LIBJIN_MODULES_THREAD
-#include "Thread.h"
+#include "je_thread.h"
namespace jin
{
diff --git a/src/libjin/Thread/Thread.h b/src/libjin/Thread/je_thread.h
index ea50444..bdbc093 100644
--- a/src/libjin/Thread/Thread.h
+++ b/src/libjin/Thread/je_thread.h
@@ -1,16 +1,16 @@
#ifndef __LIBJIN_THREAD_H
#define __LIBJIN_THREAD_H
-#include "../configuration.h"
+#include "../core/je_configuration.h"
#if LIBJIN_MODULES_THREAD
#include <string>
#include <map>
#if LIBJIN_THREAD_SDL
-# include "SDL2/SDL_thread.h"
+ #include "SDL2/SDL_thread.h"
#elif LIBJIN_THREAD_CPP
-# include <thread>
-# include <mutex>
-# include <condition_variable>
+ #include <thread>
+ #include <mutex>
+ #include <condition_variable>
#endif
namespace jin
diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp
deleted file mode 100644
index 3f2a50d..0000000
--- a/src/libjin/Thread/thread.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-#include "../configuration.h"
-#if LIBJIN_MODULES_THREAD
-
-#include "Thread.h"
-
-namespace jin
-{
- namespace thread
- {
-
- class Mutex
- {
- public:
- Mutex();
- ~Mutex();
-
- void lock();
- void unlock();
- private:
- #if LIBJIN_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 LIBJIN_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 LIBJIN_THREAD_SDL
- mutex = SDL_CreateMutex();
- #endif
- }
-
- Mutex::~Mutex()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyMutex(mutex);
- #endif
- }
-
- void Mutex::lock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_LockMutex(mutex);
- #endif
- }
-
- void Mutex::unlock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_UnlockMutex(mutex);
- #endif
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Conditional::Conditional()
- {
- #if LIBJIN_THREAD_SDL
- cond = SDL_CreateCond();
- #endif
- }
-
- Conditional::~Conditional()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyCond(cond);
- #endif
- }
-
- void Conditional::signal()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondSignal(cond);
- #endif
- }
-
- void Conditional::broadcast()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondBroadcast(cond);
- #endif
- }
-
- bool Conditional::wait(Mutex* mutex, int timeout)
- {
- #if LIBJIN_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 LIBJIN_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 LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- }
- #if LIBJIN_THREAD_SDL
- handle = SDL_CreateThread(threadRunner, name.c_str(), p);
- #elif LIBJIN_THREAD_CPP
- handle = new std::thread();
- #endif
- return (running = (handle != nullptr));
- }
-
- void Thread::wait()
- {
- {
- Lock l(mutex);
- if (!handle)
- return;
- }
- #if LIBJIN_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 thread
-} // namespace jin
-
-#endif // LIBJIN_MODULES_THREAD \ No newline at end of file
diff --git a/src/libjin/Thread/thread.h b/src/libjin/Thread/thread.h
deleted file mode 100644
index ea50444..0000000
--- a/src/libjin/Thread/thread.h
+++ /dev/null
@@ -1,166 +0,0 @@
-#ifndef __LIBJIN_THREAD_H
-#define __LIBJIN_THREAD_H
-#include "../configuration.h"
-#if LIBJIN_MODULES_THREAD
-
-#include <string>
-#include <map>
-#if LIBJIN_THREAD_SDL
-# include "SDL2/SDL_thread.h"
-#elif LIBJIN_THREAD_CPP
-# include <thread>
-# include <mutex>
-# include <condition_variable>
-#endif
-
-namespace jin
-{
- namespace thread
- {
- /**
- * ӢӢ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 LIBJIN_THREAD_SDL
- SDL_Thread* handle; // SDL thread
- #elif LIBJIN_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 thread
-} // namespace jin
-
-#endif // LIBJIN_MODULES_THREAD
-#endif // __LIBJIN_THREAD_H \ No newline at end of file