Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
d5ffa2532d
3 mainītis faili ar 31 papildinājumiem un 5 dzēšanām
  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);
+    }
   }
 }