AbstractDiskWriter::closeFile(): Throw exception if close() failed.

~AbstractDiskWriter calles closeFile(), but suppresses exception.
MultiDiskAdaptor::closeFile() logs error if child
DiskWriter::closeFile() throws exception. This exception is not
rethrown. If at least one exception is caught,
MultiDiskAdaptor::closeFile() throws new DlAbortEx.
RequestGroupMan::closeFile() just logs exception and suppress each
exception. Generally, don't call closeFile() in destructor. If you
need to call it, it must suppress the exception.
pull/4/head
Tatsuhiro Tsujikawa 2011-12-09 23:32:38 +09:00
parent 9a6f88c162
commit d5ffa2532d
3 changed files with 31 additions and 5 deletions

View File

@ -59,7 +59,10 @@ AbstractDiskWriter::AbstractDiskWriter(const std::string& filename)
AbstractDiskWriter::~AbstractDiskWriter()
{
try {
closeFile();
} catch(...) {
}
}
void AbstractDiskWriter::openFile(off_t totalLength)
@ -78,8 +81,15 @@ void AbstractDiskWriter::openFile(off_t totalLength)
void AbstractDiskWriter::closeFile()
{
if(fd_ >= 0) {
close(fd_);
int r;
while((r = close(fd_)) == -1 && errno == EINTR);
fd_ = -1;
if(r == -1) {
int errNum = errno;
throw DL_ABORT_EX3(errNum, fmt("Failed to close file: %s",
util::safeStrerror(errNum).c_str()),
error_code::FILE_IO_ERROR);
}
}
}

View File

@ -297,8 +297,20 @@ void MultiDiskAdaptor::openExistingFile()
void MultiDiskAdaptor::closeFile()
{
std::for_each(diskWriterEntries_.begin(), diskWriterEntries_.end(),
mem_fun_sh(&DiskWriterEntry::closeFile));
bool ok = true;
for(std::vector<SharedHandle<DiskWriterEntry> >::const_iterator i =
diskWriterEntries_.begin(), eoi = diskWriterEntries_.end(); i != eoi;
++i) {
try {
(*i)->closeFile();
} catch(RecoverableException& e) {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
ok = false;
}
}
if(!ok) {
throw DL_ABORT_EX("Failed to close some files");
}
}
namespace {

View File

@ -554,7 +554,11 @@ void RequestGroupMan::closeFile()
{
for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr =
requestGroups_.begin(), eoi = requestGroups_.end(); itr != eoi; ++itr) {
try {
(*itr)->closeFile();
} catch(RecoverableException& e) {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
}
}
}