Bladeren bron

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.
Tatsuhiro Tsujikawa 14 jaren geleden
bovenliggende
commit
d5ffa2532d
3 gewijzigde bestanden met toevoegingen van 31 en 5 verwijderingen
  1. 12 2
      src/AbstractDiskWriter.cc
  2. 14 2
      src/MultiDiskAdaptor.cc
  3. 5 1
      src/RequestGroupMan.cc

+ 12 - 2
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);
+    }
   }
 }
 

+ 14 - 2
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 {

+ 5 - 1
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);
+    }
   }
 }