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:
parent
9c98258ab0
commit
8962477cfa
5 changed files with 27 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue