]> git.vomp.tv Git - vompclient.git/commitdiff
Convert OsdVector::PictureReader to std::thread, stop spinning
authorChris Tallon <chris@vomp.tv>
Sat, 2 Oct 2021 16:39:15 +0000 (17:39 +0100)
committerChris Tallon <chris@vomp.tv>
Sat, 2 Oct 2021 16:39:15 +0000 (17:39 +0100)
the main loop and only wait on cond

osdvector.cc
osdvector.h
vdr.cc

index 71a6d30b73faca89b5898b4fc5011e6d9fc2363f..26072c20d3ba85d2422b69ad7c2c077575dd628a 100644 (file)
@@ -906,26 +906,51 @@ ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char
 
 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)
@@ -961,21 +986,26 @@ void OsdVector::PictureReader::removeDecoder(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();
@@ -984,38 +1014,20 @@ void OsdVector::PictureReader::threadMethod()
       {
         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();
   }
 }
 
@@ -1024,6 +1036,11 @@ void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
   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)
@@ -1031,6 +1048,7 @@ 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)
@@ -1038,9 +1056,13 @@ 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)
 {
@@ -1048,7 +1070,11 @@ 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
index 60e43ef2735900863d577facdecf4a9724c9cbd6..d93cac94d23ccbc231428a927b15af7456498977 100644 (file)
 #include <queue>
 #include <string>
 #include <mutex>
+#include <thread>
+#include <condition_variable>
 
 #include "defines.h"
 #include "messagequeue.h"
-#include "threadsystem.h"
 #include "osd.h"
 #include "colour.h"
 #include "tvmedia.h"
@@ -301,7 +302,7 @@ class OsdVector : public Osd, public MessageReceiver
         PictureReader* reader;
     };
 
-    class PictureReader: public Thread_TYPE
+    class PictureReader
     {
       public:
         ~PictureReader();
@@ -321,6 +322,11 @@ class OsdVector : public Osd, public MessageReceiver
       protected:
 
         void threadMethod();
+        std::mutex threadMutex;
+        std::thread readerThread;
+        bool threadReqQuit{};
+        std::condition_variable threadCond;
+        bool runLoop{};
 
         std::mutex pict_lock_incoming; //locks
         std::mutex decoders_lock;
diff --git a/vdr.cc b/vdr.cc
index 2a077a1ec3370b33e3e6b219225365f8b81548ae..376fe94a1b231d295a5d4f331bef2c60ee352dac 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
@@ -617,7 +617,7 @@ void VDR_PacketReceiver::call(void* userTag, bool& r_deregisterEDR, bool& r_wake
     // delete the EDR. It's made once per media requested and wasn't owned/deleted by anything before
 
     VDR_ResponsePacket* vresp = reinterpret_cast<VDR_ResponsePacket*>(userTag);
-    LogNT::getInstance()->debug(TAG, "TVMedia Pictures arrived VDR %x", vresp->getStreamID());
+    LogNT::getInstance()->debug(TAG, "TVMedia Pictures arrived VDR {:#x}", vresp->getStreamID());
     OsdVector *osd=dynamic_cast<OsdVector*>(Osd::getInstance());
     if (osd) osd->getPictReader()->receivePicture(vresp);
     // else delete vresp; //nonsense // only rpi does CHANNEL_TVMEDIA, rpi has osdvector. therefore, can't get here.