1
0
Fork 0

Fix huge multiplayer memory leak.

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.
This commit is contained in:
ThorstenB 2011-02-16 00:49:00 +01:00
parent 9c98258ab0
commit 8962477cfa
5 changed files with 27 additions and 45 deletions

View 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

View 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

View 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

View 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

View 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;