From 22ada0cf3251047ddd7a43ec6f2b2553aa0902b7 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Date: Tue, 1 Jun 2010 12:40:57 +0000 Subject: [PATCH] 2010-06-01 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> Fixed double memory free when Exception raised from AbstractCommand::prepareForNextAction() called by HttpResponseCommand::handleDefaultEncoding(). * src/AbstractCommand.cc * src/HttpResponseCommand.cc --- ChangeLog | 8 +++++ src/AbstractCommand.cc | 3 ++ src/HttpResponseCommand.cc | 60 ++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71103dae..69ec2063 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-01 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> + + Fixed double memory free when Exception raised from + AbstractCommand::prepareForNextAction() called by + HttpResponseCommand::handleDefaultEncoding(). + * src/AbstractCommand.cc + * src/HttpResponseCommand.cc + 2010-06-01 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> Added _logger->info() guard diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index b11a37fe..337babdd 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -697,6 +697,9 @@ std::string AbstractCommand::resolveHostname return ipaddr; } +// nextCommand is going to be managed by CheckIntegrityEntry which is +// created in side this function. Don't release nextCommand after this +// function call. void AbstractCommand::prepareForNextAction(Command* nextCommand) { SharedHandle<CheckIntegrityEntry> entry diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc index 6bee2be0..b316128b 100644 --- a/src/HttpResponseCommand.cc +++ b/src/HttpResponseCommand.cc @@ -233,39 +233,35 @@ bool HttpResponseCommand::handleDefaultEncoding return true; } - + _requestGroup->loadAndOpenFile(infoFile); + File file(_requestGroup->getFirstFilePath()); + // We have to make sure that command that has Request object must + // have segment after PieceStorage is initialized. See + // AbstractCommand::execute() + SharedHandle<Segment> segment = + _requestGroup->getSegmentMan()->getSegment(cuid, 0); + // pipelining requires implicit range specified. But the request for + // this response most likely dones't contains range header. This means + // we can't continue to use this socket because server sends all entity + // body instead of a segment. + // Therefore, we shutdown the socket here if pipelining is enabled. DownloadCommand* command = 0; - try { - _requestGroup->loadAndOpenFile(infoFile); - File file(_requestGroup->getFirstFilePath()); - - // We have to make sure that command that has Request object must - // have segment after PieceStorage is initialized. See - // AbstractCommand::execute() - SharedHandle<Segment> segment = - _requestGroup->getSegmentMan()->getSegment(cuid, 0); - // pipelining requires implicit range specified. But the request for - // this response most likely dones't contains range header. This means - // we can't continue to use this socket because server sends all entity - // body instead of a segment. - // Therefore, we shutdown the socket here if pipelining is enabled. - if(req->getMethod() == Request::METHOD_GET && - !segment.isNull() && segment->getPositionToWrite() == 0 && - !req->isPipeliningEnabled()) { - command = createHttpDownloadCommand - (httpResponse, getTransferEncodingDecoder(httpResponse)); - } else { - _requestGroup->getSegmentMan()->cancelSegment(cuid); - _fileEntry->poolRequest(req); - } - prepareForNextAction(command); - if(req->getMethod() == Request::METHOD_HEAD) { - poolConnection(); - req->setMethod(Request::METHOD_GET); - } - } catch(Exception& e) { - delete command; - throw; + if(req->getMethod() == Request::METHOD_GET && + !segment.isNull() && segment->getPositionToWrite() == 0 && + !req->isPipeliningEnabled()) { + command = createHttpDownloadCommand + (httpResponse, getTransferEncodingDecoder(httpResponse)); + } else { + _requestGroup->getSegmentMan()->cancelSegment(cuid); + _fileEntry->poolRequest(req); + } + // After command is passed to prepareForNextAction(), it is managed + // by CheckIntegrityEntry. + prepareForNextAction(command); + command = 0; + if(req->getMethod() == Request::METHOD_HEAD) { + poolConnection(); + req->setMethod(Request::METHOD_GET); } return true; }