From 83c31a67575ce38d780e999b3a0f60169fc8bbde Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Tue, 27 Mar 2018 17:29:24 +0200
Subject: [PATCH] ENH: use a trick to override
 ProcessObject::GetAbortGenerateData in a thread safe way

---
 .../include/otbStreamingImageVirtualWriter.h       |  4 ++--
 .../include/otbStreamingImageVirtualWriter.txx     | 12 +++++++-----
 Modules/IO/ImageIO/include/otbImageFileWriter.h    |  4 ++--
 Modules/IO/ImageIO/include/otbImageFileWriter.txx  | 13 ++++++++-----
 .../include/otbSimpleParallelTiffWriter.h          |  4 ++--
 .../include/otbSimpleParallelTiffWriter.txx        | 14 ++++++++------
 6 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.h b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.h
index 26b529fdf3..29fafc6bf5 100644
--- a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.h
+++ b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.h
@@ -143,8 +143,8 @@ public:
    *  This filter does not produce an output */
   void Update() override;
 
-  // the interface of the superclass getter function is not thread safe
-  bool GetAbortGenerateDataMutex() const;
+  /** This override doesn't return a const ref on the actual boolean */
+  const bool & GetAbortGenerateData() const override;
 
   void SetAbortGenerateData(const bool val) override;
 
diff --git a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx
index 4d724bd8b1..ec0ae5ae6d 100644
--- a/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx
+++ b/Modules/Core/Streaming/include/otbStreamingImageVirtualWriter.txx
@@ -32,6 +32,7 @@
 #include "otbTileDimensionTiledStreamingManager.h"
 #include "otbRAMDrivenTiledStreamingManager.h"
 #include "otbRAMDrivenAdaptativeStreamingManager.h"
+#include "otbUtils.h"
 
 namespace otb
 {
@@ -238,7 +239,7 @@ StreamingImageVirtualWriter<TInputImage>
    */
   InputImageRegionType streamRegion;
   for (m_CurrentDivision = 0;
-       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateDataMutex();
+       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateData();
        m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress())
     {
     streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision);
@@ -254,7 +255,7 @@ StreamingImageVirtualWriter<TInputImage>
    * If we ended due to aborting, push the progress up to 1.0 (since
    * it probably didn't end there)
    */
-  if (!this->GetAbortGenerateDataMutex())
+  if (!this->GetAbortGenerateData())
     {
     this->UpdateProgress(1.0);
     }
@@ -293,14 +294,15 @@ StreamingImageVirtualWriter<TInputImage>
 }
 
 template <class TInputImage>
-bool
+const bool &
 StreamingImageVirtualWriter<TInputImage>
-::GetAbortGenerateDataMutex() const
+::GetAbortGenerateData() const
 {
   m_Lock.Lock();
   bool ret = Superclass::GetAbortGenerateData();
   m_Lock.Unlock();
-  return ret;
+  if (ret) return otb::Utils::TrueConstant;
+  return otb::Utils::FalseConstant;
 }
 
 template <class TInputImage>
diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.h b/Modules/IO/ImageIO/include/otbImageFileWriter.h
index d8d18f634a..cbc4c6c4e9 100644
--- a/Modules/IO/ImageIO/include/otbImageFileWriter.h
+++ b/Modules/IO/ImageIO/include/otbImageFileWriter.h
@@ -200,8 +200,8 @@ public:
   itkGetObjectMacro(ImageIO, otb::ImageIOBase);
   itkGetConstObjectMacro(ImageIO, otb::ImageIOBase);
 
-  // the interface of the superclass getter function is not thread safe
-  bool GetAbortGenerateDataMutex() const;
+  /** This override doesn't return a const ref on the actual boolean */
+  const bool & GetAbortGenerateData() const override;
 
   void SetAbortGenerateData(const bool val) override;
 
diff --git a/Modules/IO/ImageIO/include/otbImageFileWriter.txx b/Modules/IO/ImageIO/include/otbImageFileWriter.txx
index 3229d46a3e..62277a49c1 100644
--- a/Modules/IO/ImageIO/include/otbImageFileWriter.txx
+++ b/Modules/IO/ImageIO/include/otbImageFileWriter.txx
@@ -48,6 +48,7 @@
 #include "otb_boost_tokenizer_header.h"
 
 #include "otbStringUtils.h"
+#include "otbUtils.h"
 
 namespace otb
 {
@@ -604,7 +605,7 @@ ImageFileWriter<TInputImage>
     }
 
   for (m_CurrentDivision = 0;
-       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateDataMutex();
+       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateData();
        m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress())
     {
     streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision);
@@ -633,7 +634,7 @@ ImageFileWriter<TInputImage>
    * If we ended due to aborting, push the progress up to 1.0 (since
    * it probably didn't end there)
    */
-  if (!this->GetAbortGenerateDataMutex())
+  if (!this->GetAbortGenerateData())
     {
     this->UpdateProgress(1.0);
     }
@@ -836,14 +837,16 @@ return this->m_FilenameHelper->GetSimpleFileName();
 }
 
 template <class TInputImage>
-bool
+const bool &
 ImageFileWriter<TInputImage>
-::GetAbortGenerateDataMutex() const
+::GetAbortGenerateData() const
 {
   m_Lock.Lock();
+  // protected read here
   bool ret = Superclass::GetAbortGenerateData();
   m_Lock.Unlock();
-  return ret;
+  if (ret) return otb::Utils::TrueConstant;
+  return otb::Utils::FalseConstant;
 }
 
 template <class TInputImage>
diff --git a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
index 8b2e9b1b8e..a7c413064a 100644
--- a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
+++ b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.h
@@ -253,8 +253,8 @@ public:
   itkSetMacro(TiffTiledMode, bool);
   itkGetMacro(TiffTiledMode, bool);
 
-  // the interface of the superclass getter function is not thread safe
-  bool GetAbortGenerateDataMutex() const;
+  /** This override doesn't return a const ref on the actual boolean */
+  const bool & GetAbortGenerateData() const override;
 
   void SetAbortGenerateData(bool val) override;
 
diff --git a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
index 4d51c77383..b037a67566 100644
--- a/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
+++ b/Modules/MPI/MPITiffWriter/include/otbSimpleParallelTiffWriter.txx
@@ -23,6 +23,7 @@
 
 #include "otbSimpleParallelTiffWriter.h"
 #include "otbStopwatch.h"
+#include "otbUtils.h"
 
 using std::vector;
 
@@ -682,7 +683,7 @@ SimpleParallelTiffWriter<TInputImage>
   double processDuration(0), writeDuration(0), numberOfProcessedRegions(0);
   InputImageRegionType streamRegion;
   for (m_CurrentDivision = 0;
-      m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateDataMutex();
+      m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateData();
       m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress())
     {
     streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision);
@@ -717,7 +718,7 @@ SimpleParallelTiffWriter<TInputImage>
     }
 
   // abort case
-  if (this->GetAbortGenerateDataMutex())
+  if (this->GetAbortGenerateData())
     {
     itk::ProcessAborted e(__FILE__, __LINE__);
     e.SetLocation(ITK_LOCATION);
@@ -768,7 +769,7 @@ SimpleParallelTiffWriter<TInputImage>
    * If we ended due to aborting, push the progress up to 1.0 (since
    * it probably didn't end there)
    */
-  if (!this->GetAbortGenerateDataMutex())
+  if (!this->GetAbortGenerateData())
     {
     this->UpdateProgress(1.0);
     }
@@ -835,14 +836,15 @@ SimpleParallelTiffWriter<TInputImage>
  }
 
 template <class TInputImage>
-bool
+const bool &
 SimpleParallelTiffWriter<TInputImage>
-::GetAbortGenerateDataMutex() const
+::GetAbortGenerateData() const
 {
   m_Lock.Lock();
   bool ret = Superclass::GetAbortGenerateData();
   m_Lock.Unlock();
-  return ret;
+  if (ret) return otb::Utils::TrueConstant;
+  return otb::Utils::FalseConstant;
 }
 
 template <class TInputImage>
-- 
GitLab