fixed memory leak when receving multi-chunk file lists

This commit is contained in:
csoler 2017-03-09 22:05:06 +01:00
parent 5b819ebd7a
commit a545481daa
2 changed files with 21 additions and 4 deletions

View File

@ -1189,8 +1189,12 @@ void p3FileDatabase::tickRecv()
{ {
case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast<RsFileListsSyncRequestItem*>(item) ) ; case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast<RsFileListsSyncRequestItem*>(item) ) ;
break ; break ;
case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: handleDirSyncResponse( dynamic_cast<RsFileListsSyncResponseItem*>(item) ) ; case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM:
break ; {
RsFileListsSyncResponseItem *sitem = dynamic_cast<RsFileListsSyncResponseItem*>(item);
handleDirSyncResponse(sitem) ;
}
break ;
default: default:
P3FILELISTS_ERROR() << "(EE) unhandled packet subtype " << item->PacketSubType() << " in " << __PRETTY_FUNCTION__ << std::endl; P3FILELISTS_ERROR() << "(EE) unhandled packet subtype " << item->PacketSubType() << " in " << __PRETTY_FUNCTION__ << std::endl;
} }
@ -1322,6 +1326,7 @@ void p3FileDatabase::splitAndSendItem(RsFileListsSyncResponseItem *ritem)
} }
// This function should not take memory ownership of ritem, so it makes copies. // This function should not take memory ownership of ritem, so it makes copies.
// The item that is returned is either created (if different from ritem) or equal to ritem.
RsFileListsSyncResponseItem *p3FileDatabase::recvAndRebuildItem(RsFileListsSyncResponseItem *ritem) RsFileListsSyncResponseItem *p3FileDatabase::recvAndRebuildItem(RsFileListsSyncResponseItem *ritem)
{ {
@ -1393,13 +1398,25 @@ RsFileListsSyncResponseItem *p3FileDatabase::recvAndRebuildItem(RsFileListsSyncR
return NULL ; return NULL ;
} }
void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *sitem) // We employ a trick in this function:
// - if recvAndRebuildItem(item) returns the same item, it has not created memory, so the incoming item should be the one to
// delete, which is done by the caller in every case.
// - if it returns a different item, it means that the item has been created below when collapsing items, so we should delete both.
// to do so, we first delete the incoming item, and replace the pointer by the new created one.
void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem*& sitem)
{ {
RsFileListsSyncResponseItem *item = recvAndRebuildItem(sitem) ; RsFileListsSyncResponseItem *item = recvAndRebuildItem(sitem) ;
if(!item) if(!item)
return ; return ;
if(item != sitem)
{
delete sitem ;
sitem = item ;
}
time_t now = time(NULL); time_t now = time(NULL);
// check the hash. If anything goes wrong (in the chunking for instance) the hash will not match // check the hash. If anything goes wrong (in the chunking for instance) the hash will not match

View File

@ -205,7 +205,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
uint32_t locked_getFriendIndex(const RsPeerId& pid); uint32_t locked_getFriendIndex(const RsPeerId& pid);
void handleDirSyncRequest (RsFileListsSyncRequestItem *) ; void handleDirSyncRequest (RsFileListsSyncRequestItem *) ;
void handleDirSyncResponse (RsFileListsSyncResponseItem *) ; void handleDirSyncResponse (RsFileListsSyncResponseItem *&) ;
std::map<RsPeerId,uint32_t> mFriendIndexMap ; std::map<RsPeerId,uint32_t> mFriendIndexMap ;
std::vector<RsPeerId> mFriendIndexTab; std::vector<RsPeerId> mFriendIndexTab;