changeset 7:bc3ca410b765

Fix freeze if the target Orthanc is not accepting images
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 26 Oct 2016 15:42:52 +0200
parents d0108402e85c
children 62adabb8c122
files Applications/ApplicationToolbox.cpp Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.cpp Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h Framework/Outputs/DicomPyramidWriter.cpp NEWS
diffstat 5 files changed, 61 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/ApplicationToolbox.cpp	Wed Oct 26 14:00:54 2016 +0200
+++ b/Applications/ApplicationToolbox.cpp	Wed Oct 26 15:42:52 2016 +0200
@@ -74,30 +74,36 @@
     {
       if (threadsCount > 1)
       {
+        // Submit the tasks to a newly-created processor
         LOG(WARNING) << "Running " << tasks.GetSize() << " tasks";
         LOG(WARNING) << "Using " << threadsCount << " threads for the computation";
         Orthanc::BagOfTasksProcessor processor(threadsCount);
         std::auto_ptr<Orthanc::BagOfTasksProcessor::Handle> handle(processor.Submit(tasks));
 
+        // Start a thread to display the progress
         bool done = false;
         boost::thread progress(PrintProgress, handle.get(), &done);
 
-        if (handle->Join())
+        // Wait for the completion of the tasks
+        bool success = handle->Join();
+
+        // Stop the progress-printing thread
+        done = true;
+        
+        if (progress.joinable())
         {
-          done = true;
+          progress.join();
+        }
+
+        if (success)
+        {
           LOG(WARNING) << "All tasks have finished";
         }
         else
         {
-          done = true;
           LOG(ERROR) << "Error has occurred, aborting";
           throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
         }
-                           
-        if (progress.joinable())
-        {
-          progress.join();
-        }
       }
       else
       {
--- a/Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.cpp	Wed Oct 26 14:00:54 2016 +0200
+++ b/Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.cpp	Wed Oct 26 15:42:52 2016 +0200
@@ -33,8 +33,10 @@
 #include "../PrecompiledHeaders.h"
 #include "BagOfTasksProcessor.h"
 
+#include "../Logging.h"
 #include "../OrthancException.h"
 
+#include <stdio.h>
 
 namespace Orthanc
 {
@@ -58,12 +60,19 @@
       {
         return command_->Execute();
       }
-      catch (OrthancException&)
+      catch (OrthancException& e)
       {
+        LOG(ERROR) << "Exception while processing a bag of tasks: " << e.What();
         return false;
       }
-      catch (std::runtime_error&)
+      catch (std::runtime_error& e)
       {
+        LOG(ERROR) << "Runtime exception while processing a bag of tasks: " << e.what();
+        return false;
+      }
+      catch (...)
+      {
+        LOG(ERROR) << "Native exception while processing a bag of tasks";
         return false;
       }
     }
@@ -75,6 +84,20 @@
   };
 
 
+  void BagOfTasksProcessor::SignalProgress(Task& task,
+                                           Bag& bag)
+  {
+    assert(bag.done_ < bag.size_);
+
+    bag.done_ += 1;
+
+    if (bag.done_ == bag.size_)
+    {
+      exitStatus_[task.GetBag()] = (bag.status_ == BagStatus_Running);
+      bagFinished_.notify_all();
+    }
+  }
+
   void BagOfTasksProcessor::Worker(BagOfTasksProcessor* that)
   {
     while (that->continue_)
@@ -93,8 +116,9 @@
 
           if (bag->second.status_ != BagStatus_Running)
           {
-            // This bag of task has failed or is tagged as canceled, do nothing
-            bag->second.done_ += 1;
+            // Do not execute this task, as its parent bag of tasks
+            // has failed or is tagged as canceled
+            that->SignalProgress(task, bag->second);
             continue;
           }
         }
@@ -112,14 +136,7 @@
             bag->second.status_ = BagStatus_Failed;
           }
 
-          assert(bag->second.done_ < bag->second.size_);
-          bag->second.done_ += 1;
-
-          if (bag->second.done_ == bag->second.size_)
-          {
-            that->exitStatus_[task.GetBag()] = (bag->second.status_ == BagStatus_Running);
-            that->bagFinished_.notify_all();
-          }
+          that->SignalProgress(task, bag->second);
         }
       }
     }
--- a/Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h	Wed Oct 26 14:00:54 2016 +0200
+++ b/Framework/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h	Wed Oct 26 15:42:52 2016 +0200
@@ -97,6 +97,9 @@
 
     float GetProgress(int64_t bag);
 
+    void SignalProgress(Task& task,
+                        Bag& bag);
+
   public:
     class Handle : public boost::noncopyable
     {
--- a/Framework/Outputs/DicomPyramidWriter.cpp	Wed Oct 26 14:00:54 2016 +0200
+++ b/Framework/Outputs/DicomPyramidWriter.cpp	Wed Oct 26 15:42:52 2016 +0200
@@ -179,7 +179,15 @@
     {
       if (writers_[i] != NULL)
       {
-        FlushInternal(*writers_[i], true);
+        try
+        {
+          FlushInternal(*writers_[i], true);
+        }
+        catch (Orthanc::OrthancException&)
+        {
+          LOG(ERROR) << "Cannot push the pending tiles to the DICOM pyramid while finalizing";
+        }
+
         delete writers_[i];
       }
     }
--- a/NEWS	Wed Oct 26 14:00:54 2016 +0200
+++ b/NEWS	Wed Oct 26 15:42:52 2016 +0200
@@ -1,3 +1,9 @@
+Pending changes in the mainline
+===============================
+
+* Fix freeze if the target Orthanc is not accepting images
+
+
 2016-10-22
 ==========