Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkImageWriteAccessor.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkImageWriteAccessor.h"
14 
16  : ImageAccessorBase(image.GetPointer(), iDI, OptionFlags), m_Image(image)
17 
18 {
19  OrganizeWriteAccess();
20 }
21 
23 {
24  // In case of non-coherent memory, copied area needs to be written back
25  // TODO
26 
27  m_Image->m_ReadWriteLock.Lock();
28 
29  // delete self from list of ImageReadAccessors in Image
30  auto it = std::find(m_Image->m_Writers.begin(), m_Image->m_Writers.end(), this);
31  m_Image->m_Writers.erase(it);
32 
33  // delete lock, if there are no waiting ImageAccessors
34  if (m_WaitLock->m_WaiterCount <= 0)
35  {
36  m_WaitLock->m_Mutex.Unlock();
37  delete m_WaitLock;
38  }
39  else
40  {
41  m_WaitLock->m_Mutex.Unlock();
42  }
43 
44  m_Image->m_ReadWriteLock.Unlock();
45 }
46 
48 {
49  return m_Image.GetPointer();
50 }
51 
52 void mitk::ImageWriteAccessor::OrganizeWriteAccess()
53 {
54  m_Image->m_ReadWriteLock.Lock();
55 
56  bool readOverlap = false;
57  bool writeOverlap = false;
58 
59  ImageAccessorWaitLock *overlapLock = nullptr;
60 
61  // Check, if there is any Read-Access going on
62  if (m_Image->m_Readers.size() > 0)
63  {
64  // Check for every ReadAccessor, if the Region of this ImageAccessors overlaps
65  // make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
66  auto it = m_Image->m_Readers.begin();
67 
68  for (; it != m_Image->m_Readers.end(); ++it)
69  {
70  ImageAccessorBase *r = *it;
71 
72  if ((r->m_Options & IgnoreLock) == 0 && Overlap(r))
73  {
74  // An Overlap was detected.
75 
77 
78  readOverlap = true;
79  overlapLock = r->m_WaitLock;
80  break;
81  } // if
82  } // for
83  } // if
84 
85  // Check, if there is any Write-Access going on
86  if (m_Image->m_Writers.size() > 0)
87  {
88  // Check for every WriteAccessor, if the Region of this ImageAccessors overlaps
89  // make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
90  auto it = m_Image->m_Writers.begin();
91 
92  for (; it != m_Image->m_Writers.end(); ++it)
93  {
94  ImageAccessorBase *w = *it;
95 
96  if ((w->m_Options & IgnoreLock) == 0 && Overlap(w))
97  {
98  // An Overlap was detected.
99 
101 
102  // save overlapping Waitlock
103  writeOverlap = true;
104  overlapLock = w->m_WaitLock;
105  break;
106 
107  } // if
108  } // for
109  } // if
110 
111  if (readOverlap || writeOverlap)
112  {
113  // Throw an exception or wait for the WriteAccessor w until it is released and start again with the request
114  // afterwards.
115  if (!(m_Options & ExceptionIfLocked))
116  {
117  // WAIT
118  overlapLock->m_WaiterCount += 1;
119  m_Image->m_ReadWriteLock.Unlock();
121 
122  // after waiting for the ImageAccessor, start this method again
123  OrganizeWriteAccess();
124  return;
125  }
126  else
127  {
128  // THROW EXCEPTION
129  m_Image->m_ReadWriteLock.Unlock();
131  << "The image part being ordered by the ImageAccessor is already in use and locked";
132  // MITK_ERROR("Speicherbereich belegt");
133  return;
134  }
135  }
136 
137  // Now, we know, that there is no conflict with a Read- or Write-Access
138  // Lock the Mutex in ImageAccessorBase, to make sure that every other ImageAccessor has to wait
139  m_WaitLock->m_Mutex.Lock();
140 
141  // insert self into Writers list in Image
142  m_Image->m_Writers.push_back(this);
143 
144  // printf("WriteAccess %d %d\n",(int) m_Image->m_Readers.size(),(int) m_Image->m_Writers.size());
145  // fflush(0);
146  m_Image->m_ReadWriteLock.Unlock();
147 }
void WaitForReleaseOf(ImageAccessorWaitLock *wL)
Uses the WaitLock to wait for another ImageAccessor.
ImageWriteAccessor(ImagePointer image, const ImageDataItem *iDI=nullptr, int OptionFlags=ImageAccessorBase::DefaultBehavior)
Orders write access for a slice, volume or 4D-Image.
~ImageWriteAccessor() override
informs Image to unlock the represented image part
unsigned int m_WaiterCount
Holds the number of ImageAccessors, which are waiting until the represented ImageAccessor is released...
bool Overlap(const ImageAccessorBase *iAB)
Computes if there is an Overlap of the image part between this instantiation and another ImageAccesso...
ImageAccessorWaitLock * m_WaitLock
Pointer to a WaitLock struct, that allows other ImageAccessors to wait for this ImageAccessor.
Image class for storing images.
Definition: mitkImage.h:72
mitk::Image::Pointer image
void PreventRecursiveMutexLock(ImageAccessorBase *iAB)
Prevents a recursive mutex lock by comparing thread ids of competing image accessors.
#define mitkThrowException(classname)
int m_Options
Stores all extended properties of an ImageAccessor. The different flags in mitk::ImageAccessorBase::O...
itk::SimpleFastMutexLock m_Mutex
A mutex that allows other ImageAccessors to wait for the represented ImageAccessor.
This struct allows to make ImageAccessors wait for this particular ImageAccessor object.
Internal class for managing references on sub-images.
const Image * GetImage() const override