OsdVector::PictureReader::~PictureReader()
{
- decoders_lock.lock();
+ threadMutex.lock();
+ if (readerThread.joinable())
+ {
+ threadReqQuit = true;
+ threadCond.notify_one();
+ threadMutex.unlock();
+ readerThread.join();
+ }
+ else
+ threadMutex.unlock();
+
+ decoders_lock.lock();
while (decoders.size())
{
PictureDecoder* dec = decoders.front();
decoders.pop_front();
delete dec;
}
-
decoders_lock.unlock();
}
void OsdVector::PictureReader::init()
{
- threadStart();
+ threadMutex.lock();
+ readerThread = std::thread( [this]
+ {
+ threadMutex.lock();
+ threadMutex.unlock();
+ threadMethod();
+ });
+ threadMutex.unlock();
}
void OsdVector::PictureReader::shutdown()
{
- threadStop();
+ std::unique_lock<std::mutex> lg(threadMutex);
+
+ if (readerThread.joinable())
+ {
+ threadReqQuit = true;
+ threadCond.notify_one();
+ lg.unlock();
+ readerThread.join();
+ }
}
void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
void OsdVector::PictureReader::threadMethod()
{
OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
- LogNT::getInstance()->debug(TAG, "TVMedia Start Picture Reader");
+ LogNT::getInstance()->debug("PictureReader", "TVMedia Start Picture Reader");
+
+ std::unique_lock<std::mutex> ul(threadMutex); // locked
while (true)
{
- if (!threadIsActive())
- {
- LogNT::getInstance()->debug(TAG, "TVMedia End Picture Reader");
- threadCheckExit();
- }
+ threadCond.wait(ul, [this]{ return threadReqQuit || runLoop; });
+ // locked
+ if (threadReqQuit) return; // unlock
+ LogNT::getInstance()->debug("PictureReader", "Running loop");
+ runLoop = false;
+ ul.unlock();
- bool todos = true;
+ // unlocked while we work
- while (todos)
+ bool miniRunAgain;
+ do
{
- todos = false;
+ miniRunAgain = false;
+
PictureInfo pictinf;
decoders_lock.lock();
std::list<PictureDecoder*>::iterator itty = decoders.begin();
{
if ((*itty)->getDecodedPicture(pictinf)) // FIXME somewhere around here?, or in getDecodedPicture, try SA optimisation
{
- todos = true;
+ miniRunAgain = true;
osdvector->createPicture(pictinf);
}
-
itty++;
}
- if (processReceivedPictures())
- {
- todos = true;
- }
-
+ if (processReceivedPictures()) miniRunAgain = true;
decoders_lock.unlock();
- }
-
- //LogNT::getInstance()->debug(TAG, "TVMedia Sleep Picture Reader");
- struct timespec target_time;
- getClockRealTime(&target_time);
+ LogNT::getInstance()->debug("PictureReader", "miniRunAgain = true...");
- target_time.tv_nsec += 1000000LL * 10;
+ } while(miniRunAgain);
- if (target_time.tv_nsec > 999999999)
- {
- target_time.tv_nsec -= 1000000000L;
- target_time.tv_sec += 1;
- }
-
- threadLock();
- threadWaitForSignalTimed(&target_time);
- threadUnlock();
- //LogNT::getInstance()->debug(TAG, "TVMedia Sleep end Picture Reader");
+ ul.lock();
}
}
pict_lock_incoming.lock();
invalid_loadindex.insert(index);
pict_lock_incoming.unlock();
+
+ // From conversion to std::thread
+ // The thread used to spin every 10ms, now it only waits on the cond
+ // This method does not signal the main thread, does it need to now?
+ // Doesn't look like it, but if it does get the 4 lines below
}
void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
pict_lock_incoming.lock();
inform_fallback[index] = fallback;
pict_lock_incoming.unlock();
+ // Also here, does this need to signal the thread?
}
void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
pict_lock_incoming.lock();
pict_incoming.push(vresp);
pict_lock_incoming.unlock();
- threadSignal();
-}
+ // These 4 lines to signal the thread
+ threadMutex.lock();
+ runLoop = true;
+ threadCond.notify_one();
+ threadMutex.unlock();
+}
void OsdVector::PictureReader::addStaticImage(unsigned int id)
{
pict_incoming_static.push(id);
invalid_loadindex.erase(((long long) id) << 32LL);
pict_lock_incoming.unlock();
- threadSignal();
+
+ threadMutex.lock();
+ runLoop = true;
+ threadCond.notify_one();
+ threadMutex.unlock();
}
#if WIN32