diff --git a/oxygine/src/ThreadLoader.cpp b/oxygine/src/ThreadLoader.cpp index 4e887ed77..8eddf6e3b 100644 --- a/oxygine/src/ThreadLoader.cpp +++ b/oxygine/src/ThreadLoader.cpp @@ -7,14 +7,23 @@ namespace oxygine { +#if OX_CPP11THREADS + ThreadLoader::ThreadLoader(): _thread(_staticThreadFunc, this), _threadDone(false) +#else ThreadLoader::ThreadLoader(): _thread(pthread_self()), _threadDone(false) +#endif { } ThreadLoader::~ThreadLoader() { +#if OX_CPP11THREADS + if(_thread.get_id() != std::this_thread::get_id()) + _thread.join(); +#else if (!pthread_equal(_thread, pthread_self())) pthread_join(_thread, 0); +#endif } @@ -122,11 +131,12 @@ namespace oxygine _load(); getStage()->addTween(TweenDummy(), 100)->addDoneCallback(CLOSURE(this, &ThreadLoader::loaded)); #else - + #if !OX_CPP11THREADS pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&_thread, &attr, _staticThreadFunc, this); + #endif #endif } -} \ No newline at end of file +} diff --git a/oxygine/src/ThreadLoader.h b/oxygine/src/ThreadLoader.h index 103dc3c8a..7c7f0469b 100644 --- a/oxygine/src/ThreadLoader.h +++ b/oxygine/src/ThreadLoader.h @@ -1,7 +1,13 @@ #pragma once #include "oxygine-include.h" #include "EventDispatcher.h" -#include "pthread.h" + +#if OX_CPP11THREADS + #include +#else + #include "pthread.h" +#endif + #include "core/ThreadDispatcher.h" #include #include "Event.h" @@ -44,7 +50,12 @@ namespace oxygine void loaded(Event*); void _load(); +#if OX_CPP11THREADS + std::thread _thread; +#else pthread_t _thread; +#endif + volatile bool _threadDone; typedef std::list resources; @@ -58,4 +69,4 @@ namespace oxygine funcs _funcs; #endif }; -} \ No newline at end of file +} diff --git a/oxygine/src/core/Mutex.cpp b/oxygine/src/core/Mutex.cpp index 212370775..dce1535cb 100644 --- a/oxygine/src/core/Mutex.cpp +++ b/oxygine/src/core/Mutex.cpp @@ -1,38 +1,79 @@ #include "Mutex.h" #include "ox_debug.h" -#include "pthread.h" +#if OX_CPP11THREADS + #include +#else + #include "pthread.h" +#endif namespace oxygine { - Mutex::Mutex(bool recursive) + Mutex::Mutex() { - if (recursive) - { - pthread_mutexattr_t mta; - pthread_mutexattr_init(&mta); - pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); - - pthread_mutex_init(&_handle, &mta); - } - else - { - pthread_mutex_init(&_handle, 0); - } +#if !OX_CPP11THREADS + pthread_mutex_init(&_handle, 0); +#endif } Mutex::~Mutex() { +#if !OX_CPP11THREADS pthread_mutex_destroy(&_handle); +#endif } void Mutex::lock() { +#if OX_CPP11THREADS + _mutex.lock(); +#else pthread_mutex_lock(&_handle); +#endif } void Mutex::unlock() { +#if OX_CPP11THREADS + _mutex.unlock(); +#else + pthread_mutex_unlock(&_handle); +#endif + } + + MutexRecursive::MutexRecursive() + { +#if !OX_CPP11THREADS + pthread_mutexattr_t mta; + pthread_mutexattr_init(&mta); + pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&_handle, &mta); +#endif + } + + MutexRecursive::~MutexRecursive() + { +#if !OX_CPP11THREADS + pthread_mutex_destroy(&_handle); +#endif + } + + void MutexRecursive::lock() + { +#if OX_CPP11THREADS + _mutex.lock(); +#else + pthread_mutex_lock(&_handle); +#endif + } + + void MutexRecursive::unlock() + { +#if OX_CPP11THREADS + _mutex.unlock(); +#else pthread_mutex_unlock(&_handle); +#endif } -} \ No newline at end of file +} diff --git a/oxygine/src/core/Mutex.h b/oxygine/src/core/Mutex.h index b99bb7930..86b86e78b 100644 --- a/oxygine/src/core/Mutex.h +++ b/oxygine/src/core/Mutex.h @@ -1,18 +1,24 @@ #pragma once #include "oxygine-include.h" +#if OX_CPP11THREADS + #include +#else + #if defined(_WIN32) && !defined(__MINGW32__) typedef struct pthread_mutex_t_* pthread_mutex_t; #else # include "pthread.h" #endif +#endif + namespace oxygine { class Mutex { public: - Mutex(bool recursive = false); + Mutex(); ~Mutex(); void lock(); @@ -22,8 +28,33 @@ namespace oxygine Mutex(const Mutex&) {} void operator = (const Mutex&) {} +#if OX_CPP11THREADS + std::mutex _mutex; +#else + pthread_mutex_t _handle; + //void *_handle; +#endif + }; + + class MutexRecursive + { + public: + MutexRecursive(); + ~MutexRecursive(); + + void lock(); + void unlock(); + + private: + MutexRecursive(const MutexRecursive&) {} + void operator = (const MutexRecursive&) {} + +#if OX_CPP11THREADS + std::recursive_mutex _mutex; +#else pthread_mutex_t _handle; //void *_handle; +#endif }; class MutexAutoLock @@ -35,4 +66,14 @@ namespace oxygine private: Mutex& _m; }; + + class MutexRecursiveAutoLock + { + public: + MutexRecursiveAutoLock(MutexRecursive& m): _m(m) {_m.lock();} + ~MutexRecursiveAutoLock() {_m.unlock();} + + private: + MutexRecursive& _m; + }; } diff --git a/oxygine/src/core/ThreadDispatcher.cpp b/oxygine/src/core/ThreadDispatcher.cpp index e987aa876..e14e55a4d 100644 --- a/oxygine/src/core/ThreadDispatcher.cpp +++ b/oxygine/src/core/ThreadDispatcher.cpp @@ -1,15 +1,25 @@ #include "ThreadDispatcher.h" #include "log.h" -#include "pthread.h" + +#if OX_CPP11THREADS + #include +#else + #include "pthread.h" +#endif + #include "Mutex.h" namespace oxygine { -#if 0 +#if OX_DEBUGTHREADING static size_t threadID() { + #if OX_CPP11THREADS + return std::this_thread::get_id().hash(); + #else pthread_t pt = pthread_self(); return ((size_t*)(&pt))[0]; + #endif } #define LOGDN(format, ...) log::messageln("ThreadMessages(%lu)::" format, threadID(), __VA_ARGS__) @@ -18,7 +28,22 @@ namespace oxygine #endif +#if OX_CPP11THREADS + MutexPthreadLock::MutexPthreadLock(std::recursive_mutex& l, bool lock) : _lock(l), _locked(false) + { + if(lock) + { + _lock.lock(); + _locked = true; + } + } + MutexPthreadLock::~MutexPthreadLock() + { + if(_locked) + _lock.unlock(); + } +#else MutexPthreadLock::MutexPthreadLock(pthread_mutex_t& m, bool lock) : _mutex(m), _locked(lock) { if (_locked) @@ -29,10 +54,16 @@ namespace oxygine { pthread_mutex_unlock(&_mutex); } +#endif +#if OX_CPP11THREADS ThreadDispatcher::ThreadDispatcher(): _id(0), _result(0) +#else + ThreadDispatcher::ThreadDispatcher(): _id(0), _result(0) +#endif { #ifndef OX_NO_MT + #if !OX_CPP11THREADS pthread_cond_init(&_cond, 0); pthread_mutexattr_t attr; @@ -40,6 +71,7 @@ namespace oxygine pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&_mutex, &attr); + #endif #endif _events.reserve(10); } @@ -47,8 +79,12 @@ namespace oxygine ThreadDispatcher::~ThreadDispatcher() { #ifndef OX_NO_MT + #if OX_CPP11THREADS + _cond.notify_all(); + #else pthread_mutex_destroy(&_mutex); pthread_cond_destroy(&_cond); + #endif #endif } @@ -58,7 +94,11 @@ namespace oxygine _replyLast(0); while (_events.empty()) + #if OX_CPP11THREADS + _cond.wait(_mutex); + #else pthread_cond_wait(&_cond, &_mutex); + #endif #endif } @@ -191,10 +231,19 @@ namespace oxygine LOGDN("replying to id=%d", _last._id); #ifndef OX_NO_MT + #if OX_CPP11THREADS + _cond.notify_all(); + #else //pthread_cond_signal(&_cond); pthread_cond_broadcast(&_cond); + #endif #endif + +#if OX_CPP11THREADS + _cond.wait(_mutex); +#else pthread_cond_wait(&_cond, &_mutex); +#endif } } @@ -206,15 +255,28 @@ namespace oxygine { LOGDN("ThreadMessages::waiting reply... _replyingTo=%d myid=%d", _replyingTo, id); #ifndef OX_NO_MT + #if OX_CPP11THREADS + _cond.notify_one(); + #else pthread_cond_signal(&_cond); + #endif #endif + +#if OX_CPP11THREADS + _cond.wait(_mutex); +#else pthread_cond_wait(&_cond, &_mutex); +#endif } while (_replyingTo != id); _last.need_reply = false; #ifndef OX_NO_MT + #if OX_CPP11THREADS + _cond.notify_one(); + #else pthread_cond_signal(&_cond); + #endif #endif } @@ -281,7 +343,11 @@ namespace oxygine msg._id = ++_id; _events.push_back(msg); #ifndef OX_NO_MT + #if OX_CPP11THREADS + _cond.notify_one(); + #else pthread_cond_signal(&_cond); + #endif #endif } @@ -367,11 +433,20 @@ namespace oxygine std::vector& ThreadDispatcher::lockMessages() { +#if OX_CPP11THREADS + _mutex.lock(); +#else pthread_mutex_lock(&_mutex); +#endif + return _events; } void ThreadDispatcher::unlockMessages() { +#if OX_CPP11THREADS + _mutex.unlock(); +#else pthread_mutex_unlock(&_mutex); +#endif } -} \ No newline at end of file +} diff --git a/oxygine/src/core/ThreadDispatcher.h b/oxygine/src/core/ThreadDispatcher.h index 91198a71f..84d1f969c 100644 --- a/oxygine/src/core/ThreadDispatcher.h +++ b/oxygine/src/core/ThreadDispatcher.h @@ -3,6 +3,12 @@ #include #include +#if OX_CPP11THREADS + #include + #include + #include +#else + #if defined(_WIN32) && !defined(__MINGW32__) typedef struct pthread_mutex_t_* pthread_mutex_t; typedef struct pthread_cond_t_* pthread_cond_t; @@ -10,8 +16,22 @@ typedef struct pthread_cond_t_* pthread_cond_t; # include "pthread.h" #endif +#endif + namespace oxygine { +#if OX_CPP11THREADS + class MutexPthreadLock + { + public: + MutexPthreadLock(std::recursive_mutex& l, bool lock = true); + ~MutexPthreadLock(); + + protected: + std::recursive_mutex& _lock; + bool _locked; + }; +#else class MutexPthreadLock { public: @@ -22,6 +42,8 @@ namespace oxygine pthread_mutex_t& _mutex; bool _locked; }; +#endif + /* class TDMessage { @@ -131,9 +153,41 @@ namespace oxygine void _popMessageNoCB(message&); void _replyLast(void* val); +#if OX_CPP11THREADS + std::recursive_mutex _mutex; + + class + { + private: + std::atomic_uint _in, _out; + + public: + void wait(std::recursive_mutex &mutex) + { + mutex.unlock(); + const unsigned int ticket = ++_in; + + while(_out < ticket) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + mutex.lock(); + } + + void notify_all() + { + _out = _in; + } + + void notify_one() + { + _out++; + } + } _cond; +#else pthread_mutex_t _mutex; pthread_cond_t _cond; +#endif typedef std::vector messages; messages _events; @@ -146,4 +200,4 @@ namespace oxygine typedef ThreadDispatcher ThreadMessages; -} \ No newline at end of file +} diff --git a/oxygine/src/core/ZipFileSystem.cpp b/oxygine/src/core/ZipFileSystem.cpp index 57df742d5..77d2eb691 100644 --- a/oxygine/src/core/ZipFileSystem.cpp +++ b/oxygine/src/core/ZipFileSystem.cpp @@ -40,7 +40,7 @@ namespace oxygine return true; } - Zips::Zips(): _lock(true) + Zips::Zips(): _sort(false) { } @@ -530,4 +530,4 @@ namespace oxygine return status_error; } } -} \ No newline at end of file +} diff --git a/oxygine/src/core/ZipFileSystem.h b/oxygine/src/core/ZipFileSystem.h index 205d4c7cb..6e7c31684 100644 --- a/oxygine/src/core/ZipFileSystem.h +++ b/oxygine/src/core/ZipFileSystem.h @@ -95,4 +95,4 @@ namespace oxygine }; } -} \ No newline at end of file +} diff --git a/oxygine/src/core/oxygine.cpp b/oxygine/src/core/oxygine.cpp index 618392264..111c4bc90 100644 --- a/oxygine/src/core/oxygine.cpp +++ b/oxygine/src/core/oxygine.cpp @@ -55,7 +55,11 @@ #include "ios/ios.h" #endif -#include "pthread.h" +#if OX_CPP11THREADS + #include +#else + #include "pthread.h" +#endif #ifdef OXYGINE_SDL extern "C" @@ -100,7 +104,11 @@ namespace oxygine spEventDispatcher _dispatcher; +#if OX_CPP11THREADS + static std::thread::id _mainThread; +#else static pthread_t _mainThread; +#endif #ifdef __S3E__ @@ -222,7 +230,11 @@ namespace oxygine #ifdef OX_NO_MT return true; #else + #if OX_CPP11THREADS + return _mainThread == std::this_thread::get_id(); + #else return pthread_equal(_mainThread, pthread_self()) != 0; + #endif #endif } @@ -450,7 +462,11 @@ namespace oxygine { #ifndef OX_NO_MT + #if OX_CPP11THREADS + _mainThread = std::this_thread::get_id(); + #else _mainThread = pthread_self(); + #endif #endif if (!_dispatcher) diff --git a/oxygine/src/res/CreateResourceContext.cpp b/oxygine/src/res/CreateResourceContext.cpp index 3c0838d3c..498b8070a 100644 --- a/oxygine/src/res/CreateResourceContext.cpp +++ b/oxygine/src/res/CreateResourceContext.cpp @@ -3,7 +3,10 @@ #include "Image.h" #include "core/ThreadDispatcher.h" #include "core/oxygine.h" -#include "pthread.h" + +#if !OX_CPP11THREADS + #include "pthread.h" +#endif namespace oxygine {