From fabb5cbd1a620ff1247fadc37920d5023918033b Mon Sep 17 00:00:00 2001
From: Chris Tallon <chris@vomp.tv>
Date: Sat, 7 Feb 2009 16:24:47 +0000
Subject: [PATCH] Vogel recursive delete

---
 boxstack.cc | 74 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 27 deletions(-)

diff --git a/boxstack.cc b/boxstack.cc
index 0778ddb..8e183a5 100644
--- a/boxstack.cc
+++ b/boxstack.cc
@@ -100,24 +100,22 @@ int BoxStack::remove(Boxx* toDelete)
 {
   if (!initted) return 0;
 
-  toDelete->preDelete();
-
-#ifndef WIN32
+  #ifndef WIN32
   pthread_mutex_lock(&boxLock);
-#else
+  #else
   WaitForSingleObject(boxLock, INFINITE);
-#endif
+  #endif
   Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for remove");  
   
   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;
+  {
+    #ifndef WIN32
+    pthread_mutex_unlock(&boxLock);
+    #else
+    ReleaseMutex(boxLock);
+    #endif
+    Log::getInstance()->log("BoxStack", Log::ERR, "Unlocked for remove numBoxes == 0");  
+    return 0;
   }
 
 //  Log::getInstance()->log("BoxStack", Log::DEBUG, "entering remove, numBoxes=%i", numBoxes);
@@ -141,18 +139,31 @@ int BoxStack::remove(Boxx* toDelete)
     if (i == -1)
     {
       // not a Box we have!
-        {           // FIXME
-            #ifndef WIN32
-            pthread_mutex_unlock(&boxLock);
-          #else
-            ReleaseMutex(boxLock);
-          #endif
-            Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");  
-              return 0;
-        }
+      // FIXME
+      #ifndef WIN32
+      pthread_mutex_unlock(&boxLock);
+      #else
+      ReleaseMutex(boxLock);
+      #endif
+      Log::getInstance()->log("BoxStack", Log::ERR, "Unlocked for remove - no boxx deleted");  
+      return 0;
     }
   }
 
+#ifndef WIN32
+  pthread_mutex_unlock(&boxLock);
+#else
+  ReleaseMutex(boxLock);
+#endif
+
+toDelete->preDelete();
+
+#ifndef WIN32
+  pthread_mutex_lock(&boxLock);
+#else
+  WaitForSingleObject(boxLock, INFINITE);
+#endif
+
 //  Log::getInstance()->log("BoxStack", Log::DEBUG, "Starting deleteBox");
   deleteBox(i);
 //  Log::getInstance()->log("BoxStack", Log::DEBUG, "Done deleteBox");
@@ -161,9 +172,6 @@ int BoxStack::remove(Boxx* toDelete)
   --numBoxes;
   for(int j = i; j < numBoxes; j++) boxes[j] = boxes[j+1];
 
-  // Delete the box
-  delete toDelete;
-
   // If there is only the wallpaper left signal command
   if (numBoxes == 1)
   {
@@ -179,6 +187,12 @@ int BoxStack::remove(Boxx* toDelete)
   ReleaseMutex(boxLock);
 #endif
   Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for remove");  
+ 
+  // Delete the box
+  //AVO: do this delete outside the lock to allow for recursive calls within the destructor
+  //     as this box is not in the stack any more, there is no chance for a second delete
+  Log::getInstance()->log("BoxStack", Log::DEBUG, "remove: going to delete boxx %p, num %d", toDelete, numBoxes);  
+  delete toDelete;
 
   return 1;
 }
@@ -467,9 +481,13 @@ void BoxStack::removeAll()
     // If boxes[numBoxes - 1] isn't toDel then there's a problem
     if (boxes[numBoxes - 1] == toDel)
     {
-      delete toDel;
       --numBoxes;
     }
+    else
+    {
+      Log::getInstance()->log("BoxStack", Log::ERR, "Can this actually happen? Why?");
+      toDel = NULL;
+    }
 
     #ifndef WIN32
       pthread_mutex_unlock(&boxLock);
@@ -477,8 +495,10 @@ void BoxStack::removeAll()
       ReleaseMutex(boxLock);
     #endif
 
+    //AVO: do the delete outside the lock to allow for recursive deletes
+    Log::getInstance()->log("BoxStack", Log::DEBUG, "going to delete boxx %p, num=%d", toDel, numBoxes);
+    if (toDel) delete toDel;
   }
-
 }
 
 int BoxStack::handleCommand(int command)
-- 
2.39.5