summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-12-09 23:32:38 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-12-09 23:32:38 +0900
commitd5ffa2532da9283abaf18d5ca4e58d07a8b2f405 (patch)
tree25ce2972b76194c42f1b283f814f837d53b10c25
parent9a6f88c162bc49d8e5bbefdcd2cf239706c3d0d9 (diff)
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.
-rw-r--r--src/AbstractDiskWriter.cc14
-rw-r--r--src/MultiDiskAdaptor.cc16
-rw-r--r--src/RequestGroupMan.cc6
3 files changed, 31 insertions, 5 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index e209018a..fb6a0174 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -59,7 +59,10 @@ AbstractDiskWriter::AbstractDiskWriter(const std::string& filename)
AbstractDiskWriter::~AbstractDiskWriter()
{
- closeFile();
+ 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);
+ }
}
}
diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc
index 17f3198d..3cb464ff 100644
--- a/src/MultiDiskAdaptor.cc
+++ b/src/MultiDiskAdaptor.cc
@@ -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 {
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc
index 34e9e127..6aeae42d 100644
--- a/src/RequestGroupMan.cc
+++ b/src/RequestGroupMan.cc
@@ -554,7 +554,11 @@ void RequestGroupMan::closeFile()
{
for(std::deque<SharedHandle<RequestGroup> >::const_iterator itr =
requestGroups_.begin(), eoi = requestGroups_.end(); itr != eoi; ++itr) {
- (*itr)->closeFile();
+ try {
+ (*itr)->closeFile();
+ } catch(RecoverableException& e) {
+ A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
+ }
}
}