]> git.vomp.tv Git - vompclient.git/commitdiff
Fix timercall/boxstack->update thread clash with boxstack->remove
authorChris Tallon <chris@vomp.tv>
Mon, 2 Jun 2008 21:53:57 +0000 (21:53 +0000)
committerChris Tallon <chris@vomp.tv>
Mon, 2 Jun 2008 21:53:57 +0000 (21:53 +0000)
18 files changed:
boxstack.cc
boxx.h
vaudioplayer.cc
vaudioplayer.h
vepg.cc
vepg.h
vpicture.cc
vpicture.h
vradiorec.cc
vradiorec.h
vtimerlist.cc
vtimerlist.h
vvideolivetv.cc
vvideolivetv.h
vvideorec.cc
vvideorec.h
vwelcome.cc
vwelcome.h

index e4c620f466b0d6d94eae85cf9a074d10f9e9e435..896b42c8a15fe93a0e6070cbac781d75417d21ae 100644 (file)
@@ -78,6 +78,7 @@ int BoxStack::add(Boxx* v)
 #else
   WaitForSingleObject(boxLock, INFINITE);
 #endif
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for add");  
   
   if (numBoxes == 16) return 0;
   boxes[numBoxes++] = v;
@@ -88,6 +89,8 @@ int BoxStack::add(Boxx* v)
   ReleaseMutex(boxLock);
 #endif
 
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for add");
+  
   return 1;
 }
 
@@ -96,14 +99,26 @@ int BoxStack::add(Boxx* v)
 int BoxStack::remove(Boxx* toDelete)
 {
   if (!initted) return 0;
-  
+
+  toDelete->preDelete();
+
 #ifndef WIN32
   pthread_mutex_lock(&boxLock);
 #else
   WaitForSingleObject(boxLock, INFINITE);
 #endif
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for remove");  
   
-  if (numBoxes == 0) return 0;
+  if (numBoxes == 0)
+  {           // FIXME
+            #ifndef WIN32
+            pthread_mutex_unlock(&boxLock);
+          #else
+            ReleaseMutex(boxLock);
+          #endif
+            Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");  
+              return 0;
+  }
 
 //  Log::getInstance()->log("BoxStack", Log::DEBUG, "entering remove, numBoxes=%i", numBoxes);
 
@@ -126,7 +141,15 @@ int BoxStack::remove(Boxx* toDelete)
     if (i == -1)
     {
       // not a Box we have!
-      return 0;
+        {           // FIXME
+            #ifndef WIN32
+            pthread_mutex_unlock(&boxLock);
+          #else
+            ReleaseMutex(boxLock);
+          #endif
+            Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");  
+              return 0;
+        }
     }
   }
 
@@ -155,6 +178,7 @@ int BoxStack::remove(Boxx* toDelete)
 #else
   ReleaseMutex(boxLock);
 #endif
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");  
 
   return 1;
 }
@@ -227,12 +251,12 @@ void BoxStack::update(Boxx* toUpdate, Region* regionToUpdate)
     rl.pop_front();
   }
   
-  Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocking");
 #ifndef WIN32
   pthread_mutex_unlock(&boxLock);
 #else
   ReleaseMutex(boxLock);
 #endif  
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for update");
 }
 
 void BoxStack::repaintRevealed(int x, Region r)
diff --git a/boxx.h b/boxx.h
index 11a8366f53d6c2a7997f3dc93d24abdd32cda435..f9da2e1bfd2a69b1db422f6ad6afccd16c72162e 100644 (file)
--- a/boxx.h
+++ b/boxx.h
@@ -56,12 +56,21 @@ class Boxx
     // The following are supposed to be abstract functions
     // However, it is useful to be able to make instances of Boxx
     // Therefore the following stubs are provided.
+    virtual void preDelete() {}
     virtual int handleCommand(int x) { return 0; }
     virtual void processMessage(Message* m) {}
     virtual bool mouseMove(int x, int y) { return false; }
     virtual bool mouseLBDOWN(int x, int y) { return false; }
     virtual void deactivateAllControls() {}
 
+    /* preDelete 
+    
+     I think it's functionally equivalent to e.g. delete timers in Boxx::preDelete
+     because the only place where a Boxx is deleted is in 
+     BoxStack::remove. There is now a call in BoxStack::remove to Boxx::preDelete
+     The reason for this is to stop timercalls calling BoxStack::update at the
+     same time BoxStack::remove is locked trying to delete the Boxx
+    */
 
     // Get functions
     int getScreenX();        // where is it on screen
index b50feb3c8db9d4298a06517fda67ae116dc5602c..882e8b705833dfae7f39743e601cb5e1d5745b63 100644 (file)
@@ -66,6 +66,16 @@ AudioPlayer * VAudioplayer::getPlayer(bool createIfNeeded)
   return rt;
 }
 
+void VAudioplayer::preDelete()
+{
+  // Another note from Chris:
+  // I have moved these timer cancels here from the destructor, please see boxx.h
+
+  Timers::getInstance()->cancelTimer(this,1);
+  Timers::getInstance()->cancelTimer(this,2);
+  Timers::getInstance()->cancelTimer(this,3);
+}
+
 VAudioplayer::~VAudioplayer()
 {
   // Note from Chris:
@@ -78,9 +88,8 @@ VAudioplayer::~VAudioplayer()
   if (banner) BoxStack::getInstance()->remove(banner);
   if (fullname) delete fullname;
   if (filename) delete filename;
-  Timers::getInstance()->cancelTimer(this,1);
-  Timers::getInstance()->cancelTimer(this,2);
-  Timers::getInstance()->cancelTimer(this,3);
+
+
   //TODO leave this to medialist and stop only...
   if (getPlayer(false)) {
     AudioPlayer::getInstance(NULL,false)->shutdown();
index 219ea76ac645baa804ebeedcceb22b0fa56b18dc..e8746adc66153085d81afdba81b3e5f442b4c22a 100644 (file)
@@ -47,6 +47,7 @@ class VAudioplayer : public TBBoxx, public TimerReceiver
 
     void processMessage(Message* m);
     int handleCommand(int command);
+    void preDelete();
     void draw();
     void timercall(int clientReference);
     //factory method
diff --git a/vepg.cc b/vepg.cc
index f6dfb55fa9d56f030868f100c118b6e4de9ffa1c..3531d0290cedd579cb85971651ac600c897787da 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -161,9 +161,13 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ULONG streamType)
   updateEventList(); // get list of programmes
 }
 
-VEpg::~VEpg()
+void VEpg::preDelete()
 {
   Timers::getInstance()->cancelTimer(this, 1);
+}
+
+VEpg::~VEpg()
+{
 
   instance = NULL;
 
diff --git a/vepg.h b/vepg.h
index 59db20cd2559bbb0682641be1dd245ec6f2f4b5f..edef8a6f49a72e2040c02e93fce7a84d9b8fd13e 100644 (file)
--- a/vepg.h
+++ b/vepg.h
@@ -48,6 +48,7 @@ class VEpg : public Boxx, public TimerReceiver
     ~VEpg();
     static VEpg* getInstance();
 
+    void preDelete();
     int handleCommand(int command); // deal with commands (from remote control)
     void draw(); // draw epg view
     void processMessage(Message* m);
index 7ad5f433b21cca923784aa9e7d2b0052bb537fc1..28320df64b0f7c93c6df5132104074d1b455d883 100644 (file)
@@ -90,15 +90,20 @@ VPicture::VPicture(VMediaList *p)
   add(&jpeg);
 }
 
+void VPicture::preDelete()
+{
+  Timers::getInstance()->cancelTimer(this,1);
+  Timers::getInstance()->cancelTimer(this,2);
+  Timers::getInstance()->cancelTimer(this,3);
+}
+
 VPicture::~VPicture()
 {
   delete reader;
   if (banner) BoxStack::getInstance()->remove(banner);
   if (fullname) delete fullname;
   if (filename) delete filename;
-  Timers::getInstance()->cancelTimer(this,1);
-  Timers::getInstance()->cancelTimer(this,2);
-  Timers::getInstance()->cancelTimer(this,3);
+
   destroyInfo();
   
 }
index 0f54c7291d511e72e1d7fa9978992ca2caef8760..a55a6c080ab894eda3fd49cede346228afb93c51 100644 (file)
@@ -46,6 +46,7 @@ class VPicture : public Boxx, public TimerReceiver
   public:
     ~VPicture();
 
+    void preDelete();
     void processMessage(Message* m);
     int handleCommand(int command);
     void draw();
index 5c8737f41c2b5d6e2622d17f4b8eddf14b71cc33..810a4f6f3d28861f4bee45ee542851283e58cad8 100644 (file)
@@ -92,12 +92,16 @@ VRadioRec::VRadioRec(Recording* rec)
   barShowing = false;
 }
 
+void VRadioRec::preDelete()
+{
+  timers->cancelTimer(this, 1);
+  timers->cancelTimer(this, 2);
+}
+
 VRadioRec::~VRadioRec()
 {
   if (playing) stopPlay();
 
-  timers->cancelTimer(this, 1);
-  timers->cancelTimer(this, 2);
 
   // kill recInfo in case resumePoint has changed (likely)
   myRec->dropRecInfo();
index b7cc103578a76a8d705323fe7c030a927a383f15..73db089693e7158e2053e4b043925bb427b65409 100644 (file)
@@ -42,6 +42,7 @@ class VRadioRec : public Boxx, public TimerReceiver
     VRadioRec(Recording* rec);
     ~VRadioRec();
     void draw();
+    void preDelete();
     int handleCommand(int command);
     void go();
 
index 23d6cd78cf95a22c8daf9b6232dcf0d4bb7e3165..d2b38eaeaaf2106a8e7946a472105bbe2ead87ae 100644 (file)
@@ -69,9 +69,13 @@ VTimerList::VTimerList()
   add(&sl);
 }
 
-VTimerList::~VTimerList()
+void VTimerList::preDelete()
 {
   Timers::getInstance()->cancelTimer(this, 1);
+}
+
+VTimerList::~VTimerList()
+{
   if (recTimerList)
   {
     for (UINT i = 0; i < recTimerList->size(); i++)
index c3690a224ba74e43aa4e2a9e248bd74c2aaa5483..a7f6a10dbcb880edd920e03463e3b9e7de534594 100644 (file)
@@ -38,6 +38,7 @@ class VTimerList : public TBBoxx, public TimerReceiver
   public:
     VTimerList();
     ~VTimerList();
+    void preDelete();
 
     int handleCommand(int command);
     void timercall(int clientReference);
index 358b3cd1afc61ea28942bb5cfbedf5513c0cae82..53599e5b140d7afe3dbdeb121e31eb951ae576b4 100644 (file)
@@ -235,10 +235,13 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V
   osdSummaryRegion = r1 + r2;
 }
 
-VVideoLiveTV::~VVideoLiveTV()
+void VVideoLiveTV::preDelete()
 {
   if (playing) stop();
+}
 
+VVideoLiveTV::~VVideoLiveTV()
+{
   delete player;
   video->setDefaultAspect();
   delData();
index 54a55f675c49d4462abda0e01e3ee132cd461d60..d261d98c3aad5ec0a853d78319aaa790f9527006 100644 (file)
@@ -48,6 +48,7 @@ class VVideoLiveTV : public Boxx, public TimerReceiver
   public:
     VVideoLiveTV(ChannelList* chanList, ULONG initialChannelNumber, VChannelList* vchannelList);
     ~VVideoLiveTV();
+    void preDelete();
     int handleCommand(int command);
     void processMessage(Message* m);
 
index 0475d98847b4af2ed3de4145db1bda5832c9968c..913d1bcf3a0d1fb17c09c26596d3c378ee66935b 100644 (file)
@@ -125,6 +125,12 @@ VVideoRec::VVideoRec(Recording* rec)
   }
 }
 
+void VVideoRec::preDelete()
+{
+  timers->cancelTimer(this, 1);
+  timers->cancelTimer(this, 2);
+}
+
 VVideoRec::~VVideoRec()
 {
   Log::getInstance()->log("VVideoRec", Log::DEBUG, "Entering vvideorec destructor");
@@ -140,9 +146,6 @@ VVideoRec::~VVideoRec()
   if (playing) stopPlay();
   video->setDefaultAspect();
 
-  timers->cancelTimer(this, 1);
-  timers->cancelTimer(this, 2);
-
   // kill recInfo in case resumePoint has changed (likely)
   myRec->dropRecInfo();
   // FIXME - do this properly - save the resume point back to the server manually and update
index a00f0038fe602ece4e711a09954529bf203962c8..36f5231482c2b224ff3b45033e6ac95ac14e2e9f 100644 (file)
@@ -46,6 +46,7 @@ class VVideoRec : public Boxx, public TimerReceiver
   public:
     VVideoRec(Recording* rec);
     ~VVideoRec();
+    void preDelete();
     int handleCommand(int command);
     void go(bool resume);
 
index 63253098ea7fd3a0d4d6196ffdfcbc2447288e6b..6306fc6094d66e1222404355b5c87776a7e2234a 100644 (file)
@@ -77,11 +77,15 @@ VWelcome::VWelcome()
   add(&jpeg);
 }
 
-VWelcome::~VWelcome()
+void VWelcome::preDelete()
 {
   Timers::getInstance()->cancelTimer(this, 1);
 }
 
+VWelcome::~VWelcome()
+{
+}
+
 void VWelcome::draw()
 {
   TBBoxx::draw();
index ced2fb5ff1c19d3c8f5aace8fb534c1cb54bb993..90cf754debe29228e14470304aac15977e16560a 100644 (file)
@@ -40,7 +40,7 @@ class VWelcome : public TBBoxx, public TimerReceiver
     ~VWelcome();
 
     void create();
-
+    void preDelete();
     int handleCommand(int command);
     void processMessage(Message* m);
     void draw();