diff --git a/src/modules/thread/Channel.cpp b/src/modules/thread/Channel.cpp index f85526eda..8d6180178 100644 --- a/src/modules/thread/Channel.cpp +++ b/src/modules/thread/Channel.cpp @@ -77,8 +77,6 @@ Channel::Channel() , sent(0) , received(0) { - mutex = newMutex(); - cond = newConditional(); } Channel::Channel(const std::string &name) @@ -87,15 +85,10 @@ Channel::Channel(const std::string &name) , sent(0) , received(0) { - mutex = newMutex(); - cond = newConditional(); } Channel::~Channel() { - delete mutex; - delete cond; - if (named) { Lock l(namedChannelMutex); diff --git a/src/modules/thread/Channel.h b/src/modules/thread/Channel.h index da98f9da9..b257415a0 100644 --- a/src/modules/thread/Channel.h +++ b/src/modules/thread/Channel.h @@ -60,8 +60,8 @@ private: void lockMutex(); void unlockMutex(); - Mutex *mutex; - Conditional *cond; + MutexRef mutex; + ConditionalRef cond; std::queue queue; bool named; std::string name; diff --git a/src/modules/thread/threads.cpp b/src/modules/thread/threads.cpp index cf20e5340..ad5f314f5 100644 --- a/src/modules/thread/threads.cpp +++ b/src/modules/thread/threads.cpp @@ -43,7 +43,7 @@ Lock::~Lock() } EmptyLock::EmptyLock() - : mutex(0) + : mutex(nullptr) { } @@ -119,5 +119,30 @@ MutexRef::operator Mutex*() const return mutex; } +Mutex *MutexRef::operator->() const +{ + return mutex; +} + +ConditionalRef::ConditionalRef() + : conditional(newConditional()) +{ +} + +ConditionalRef::~ConditionalRef() +{ + delete conditional; +} + +ConditionalRef::operator Conditional*() const +{ + return conditional; +} + +Conditional *ConditionalRef::operator->() const +{ + return conditional; +} + } // thread } // love diff --git a/src/modules/thread/threads.h b/src/modules/thread/threads.h index ff7b01e45..190aa0170 100644 --- a/src/modules/thread/threads.h +++ b/src/modules/thread/threads.h @@ -103,11 +103,25 @@ public: ~MutexRef(); operator Mutex*() const; + Mutex *operator->() const; private: Mutex *mutex; }; +class ConditionalRef +{ +public: + ConditionalRef(); + ~ConditionalRef(); + + operator Conditional*() const; + Conditional *operator->() const; + +private: + Conditional *conditional; +}; + Mutex *newMutex(); Conditional *newConditional(); Thread *newThread(Threadable *t); diff --git a/src/modules/timer/Timer.cpp b/src/modules/timer/Timer.cpp index 4cd4aaea2..c9737842d 100644 --- a/src/modules/timer/Timer.cpp +++ b/src/modules/timer/Timer.cpp @@ -114,7 +114,7 @@ double Timer::getTimerPeriod() return 0; } -double Timer::getTimeSinceEpoch() +double Timer::getTime() { // The timer period (reciprocal of the frequency.) static const double timerPeriod = getTimerPeriod(); @@ -145,10 +145,5 @@ double Timer::getTimeSinceEpoch() #endif } -double Timer::getTime() const -{ - return getTimeSinceEpoch(); -} - } // timer } // love diff --git a/src/modules/timer/Timer.h b/src/modules/timer/Timer.h index 3d9eda136..53d94e843 100644 --- a/src/modules/timer/Timer.h +++ b/src/modules/timer/Timer.h @@ -76,8 +76,7 @@ public: * and increases monotonically. * @return The time (in seconds) **/ - virtual double getTime() const; - static double getTimeSinceEpoch(); + static double getTime(); private: diff --git a/src/modules/video/theora/Video.cpp b/src/modules/video/theora/Video.cpp index 9f02247fc..2daa6e950 100644 --- a/src/modules/video/theora/Video.cpp +++ b/src/modules/video/theora/Video.cpp @@ -71,6 +71,7 @@ void Worker::addStream(VideoStream *stream) { love::thread::Lock l(mutex); streams.push_back(stream); + cond->broadcast(); } void Worker::stop() @@ -78,6 +79,7 @@ void Worker::stop() { love::thread::Lock l(mutex); stopping = true; + cond->broadcast(); } owner->wait(); @@ -85,34 +87,39 @@ void Worker::stop() void Worker::threadFunction() { - double lastFrame = love::timer::Timer::getTimeSinceEpoch(); + double lastFrame = love::timer::Timer::getTime(); + while (true) { - double curFrame = love::timer::Timer::getTimeSinceEpoch(); + love::sleep(2); + + love::thread::Lock l(mutex); + + while (!stopping && streams.empty()) + { + cond->wait(mutex); + lastFrame = love::timer::Timer::getTime(); + } + + if (stopping) + return; + + double curFrame = love::timer::Timer::getTime(); double dt = curFrame-lastFrame; lastFrame = curFrame; + for (auto it = streams.begin(); it != streams.end(); ++it) { - love::thread::Lock l(mutex); - - if (stopping) - return; - - for (auto it = streams.begin(); it != streams.end(); ++it) + VideoStream *stream = *it; + if (stream->getReferenceCount() == 1) { - VideoStream *stream = *it; - if (stream->getReferenceCount() == 1) - { - // We're the only ones left - streams.erase(it); - break; - } - - stream->threadedFillBackBuffer(dt); + // We're the only ones left + streams.erase(it); + break; } - } - love::sleep(2); + stream->threadedFillBackBuffer(dt); + } } } diff --git a/src/modules/video/theora/Video.h b/src/modules/video/theora/Video.h index 741dc0582..4eba5888e 100644 --- a/src/modules/video/theora/Video.h +++ b/src/modules/video/theora/Video.h @@ -68,10 +68,13 @@ public: void stop(); private: - std::vector> streams; - love::thread::MutexRef mutex; - volatile bool stopping; + std::vector> streams; + + love::thread::MutexRef mutex; + love::thread::ConditionalRef cond; + + bool stopping; }; // Worker } // theora