]> git.mxchange.org Git - flightgear.git/commitdiff
Fix huge multiplayer memory leak.
authorThorstenB <brehmt@gmail.com>
Tue, 15 Feb 2011 23:49:00 +0000 (00:49 +0100)
committerThorstenB <brehmt@gmail.com>
Tue, 15 Feb 2011 23:49:00 +0000 (00:49 +0100)
Almost all FGPropertyData elements received via MP were leaked.
Property data is now cleanly deallocated in the FGExternalMotionData destructor.
Thanks to Jester for reporting rising mem consumption in MP mode.

src/AIModel/AIMultiplayer.cxx
src/AIModel/AIMultiplayer.hxx
src/MultiPlayer/mpmessages.hxx
src/MultiPlayer/multiplaymgr.cxx
src/Network/multiplay.cxx

index 476ddf205b54e1de4f3aa71ac315dab62ff240df..0652dfef73751daf52f67997d72028ef2e6ad916 100644 (file)
@@ -335,35 +335,13 @@ void FGAIMultiplayer::update(double dt)
       if (prevIt != mMotionInfo.begin()) 
       {
         --prevIt;
-        
-        MotionInfo::iterator delIt;
-        delIt = mMotionInfo.begin();
-        
-        while (delIt != prevIt) 
-        {
-          std::vector<FGPropertyData*>::const_iterator propIt;
-          std::vector<FGPropertyData*>::const_iterator propItEnd;
-          propIt = delIt->second.properties.begin();
-          propItEnd = delIt->second.properties.end();
-
-          //cout << "Deleting data\n";
-          
-          while (propIt != propItEnd)
-          {
-            delete *propIt;
-            propIt++;
-          }
-          
-          delIt++;
-        }
-        
         mMotionInfo.erase(mMotionInfo.begin(), prevIt);
       }
     }
   } else {
     // Ok, we need to predict the future, so, take the best data we can have
     // and do some eom computation to guess that for now.
-    FGExternalMotionData motionInfo = it->second;
+    FGExternalMotionData& motionInfo = it->second;
 
     // The time to predict, limit to 5 seconds
     double t = tInterp - motionInfo.time;
@@ -488,7 +466,7 @@ void FGAIMultiplayer::update(double dt)
 }
 
 void
-FGAIMultiplayer::addMotionInfo(const FGExternalMotionData& motionInfo,
+FGAIMultiplayer::addMotionInfo(FGExternalMotionData& motionInfo,
                                long stamp)
 {
   mLastTimestamp = stamp;
@@ -505,6 +483,9 @@ FGAIMultiplayer::addMotionInfo(const FGExternalMotionData& motionInfo,
       return;
   }
   mMotionInfo[motionInfo.time] = motionInfo;
+  // We just copied the property (pointer) list - they are ours now. Clear the
+  // properties list in given/returned object, so former owner won't deallocate them.
+  motionInfo.properties.clear();
 }
 
 void
index e484dacb016ff5971a631f392f1cd892eeb3f4bd..d79f0c20614cef4f7b9d6f74a20de1953ff8981f 100644 (file)
@@ -37,7 +37,7 @@ public:
   virtual void unbind();
   virtual void update(double dt);
 
-  void addMotionInfo(const FGExternalMotionData& motionInfo, long stamp);
+  void addMotionInfo(FGExternalMotionData& motionInfo, long stamp);
   void setDoubleProperty(const std::string& prop, double val);
 
   long getLastTimestamp(void) const
index dded2b3e2175819b6fa1eef626e4f66b853c48ff..f5b89eb8269933726ca4da8438fe1efe1c32d5f0 100644 (file)
@@ -141,7 +141,7 @@ struct FGExternalMotionData {
   // simulation time when this packet was generated
   double time;
   // the artificial lag the client should stay behind the average
-  // simulation time to arrival time diference
+  // simulation time to arrival time difference
   // FIXME: should be some 'per model' instead of 'per packet' property
   double lag;
   
@@ -166,6 +166,20 @@ struct FGExternalMotionData {
   
   // The set of properties recieved for this timeslot
   std::vector<FGPropertyData*> properties;
+
+  ~FGExternalMotionData()
+  {
+      std::vector<FGPropertyData*>::const_iterator propIt;
+      std::vector<FGPropertyData*>::const_iterator propItEnd;
+      propIt = properties.begin();
+      propItEnd = properties.end();
+
+      while (propIt != propItEnd)
+      {
+        delete *propIt;
+        propIt++;
+      }
+  }
 };
 
 #endif
index 7657ad4ee06cf0dd7ba405f222daf94e29dd39fa..9a541382786f10de1cabd9433d103e07ba0e5de4 100644 (file)
@@ -923,19 +923,20 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
       goto noprops;
   }
   while (xdr < Msg.propsRecvdEnd()) {
-    FGPropertyData* pData = new FGPropertyData;
     // simgear::props::Type type = simgear::props::UNSPECIFIED;
     
     // First element is always the ID
-    pData->id = XDR_decode_uint32(*xdr);
+    unsigned id = XDR_decode_uint32(*xdr);
     //cout << pData->id << " ";
     xdr++;
     
     // Check the ID actually exists and get the type
-    const IdPropertyList* plist = findProperty(pData->id);
+    const IdPropertyList* plist = findProperty(id);
     
     if (plist)
     {
+      FGPropertyData* pData = new FGPropertyData;
+      pData->id = id;
       pData->type = plist->type;
       // How we decode the remainder of the property depends on the type
       switch (pData->type) {
@@ -1001,7 +1002,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
       // We failed to find the property. We'll try the next packet immediately.
       SG_LOG(SG_NETWORK, SG_INFO, "FGMultiplayMgr::ProcessPosMsg - "
              "message from " << MsgHdr->Callsign << " has unknown property id "
-             << pData->id); 
+             << id); 
     }
   }
  noprops:
@@ -1015,7 +1016,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
 //////////////////////////////////////////////////////////////////////
 //
 //  handle a chat message
-//  FIXME: display chat message withi flightgear
+//  FIXME: display chat message within flightgear
 //
 //////////////////////////////////////////////////////////////////////
 void
index a9cd32bf3823009c0fb6002270d321b993f35c35..ddedccea8047f3144a2a0c17d67a5c0bf0498359 100644 (file)
@@ -283,20 +283,6 @@ bool FGMultiplay::process() {
 
     FGMultiplayMgr* mpmgr = (FGMultiplayMgr*) globals->get_subsystem("mp");
     mpmgr->SendMyPosition(motionInfo);
-    
-    // Now remove the data
-    std::vector<FGPropertyData*>::const_iterator propIt;
-    std::vector<FGPropertyData*>::const_iterator propItEnd;
-    propIt = motionInfo.properties.begin();
-    propItEnd = motionInfo.properties.end();
-
-    //cout << "Deleting data\n";
-
-    while (propIt != propItEnd)
-    {
-      delete *propIt;
-      propIt++;
-    }    
   }
 
   return true;