Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkImageWriteAccessor.h"
18 
20  : ImageAccessorBase(image.GetPointer(), iDI, OptionFlags), m_Image(image)
21 
22 {
23  OrganizeWriteAccess();
24 }
25 
27 {
28  // In case of non-coherent memory, copied area needs to be written back
29  // TODO
30 
31  m_Image->m_ReadWriteLock.Lock();
32 
33  // delete self from list of ImageReadAccessors in Image
34  auto it = std::find(m_Image->m_Writers.begin(), m_Image->m_Writers.end(), this);
35  m_Image->m_Writers.erase(it);
36 
37  // delete lock, if there are no waiting ImageAccessors
38  if (m_WaitLock->m_WaiterCount <= 0)
39  {
40  m_WaitLock->m_Mutex.Unlock();
41  delete m_WaitLock;
42  }
43  else
44  {
45  m_WaitLock->m_Mutex.Unlock();
46  }
47 
48  m_Image->m_ReadWriteLock.Unlock();
49 }
50 
52 {
53  return m_Image.GetPointer();
54 }
55 
56 void mitk::ImageWriteAccessor::OrganizeWriteAccess()
57 {
58  m_Image->m_ReadWriteLock.Lock();
59 
60  bool readOverlap = false;
61  bool writeOverlap = false;
62 
63  ImageAccessorWaitLock *overlapLock = nullptr;
64 
65  // Check, if there is any Read-Access going on
66  if (m_Image->m_Readers.size() > 0)
67  {
68  // Check for every ReadAccessor, if the Region of this ImageAccessors overlaps
69  // make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
70  auto it = m_Image->m_Readers.begin();
71 
72  for (; it != m_Image->m_Readers.end(); ++it)
73  {
74  ImageAccessorBase *r = *it;
75 
76  if ((r->m_Options & IgnoreLock) == 0 && Overlap(r))
77  {
78  // An Overlap was detected.
79 
80  PreventRecursiveMutexLock(r);
81 
82  readOverlap = true;
83  overlapLock = r->m_WaitLock;
84  break;
85  } // if
86  } // for
87  } // if
88 
89  // Check, if there is any Write-Access going on
90  if (m_Image->m_Writers.size() > 0)
91  {
92  // Check for every WriteAccessor, if the Region of this ImageAccessors overlaps
93  // make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
94  auto it = m_Image->m_Writers.begin();
95 
96  for (; it != m_Image->m_Writers.end(); ++it)
97  {
98  ImageAccessorBase *w = *it;
99 
100  if (Overlap(w))
101  {
102  // An Overlap was detected.
103 
104  PreventRecursiveMutexLock(w);
105 
106  // save overlapping Waitlock
107  writeOverlap = true;
108  overlapLock = w->m_WaitLock;
109  break;
110 
111  } // if
112  } // for
113  } // if
114 
115  if (readOverlap || writeOverlap)
116  {
117  // Throw an exception or wait for the WriteAccessor w until it is released and start again with the request
118  // afterwards.
119  if (!(m_Options & ExceptionIfLocked))
120  {
121  // WAIT
122  overlapLock->m_WaiterCount += 1;
123  m_Image->m_ReadWriteLock.Unlock();
125 
126  // after waiting for the ImageAccessor, start this method again
127  OrganizeWriteAccess();
128  return;
129  }
130  else
131  {
132  // THROW EXCEPTION
133  m_Image->m_ReadWriteLock.Unlock();
135  << "The image part being ordered by the ImageAccessor is already in use and locked";
136  // MITK_ERROR("Speicherbereich belegt");
137  return;
138  }
139  }
140 
141  // Now, we know, that there is no conflict with a Read- or Write-Access
142  // Lock the Mutex in ImageAccessorBase, to make sure that every other ImageAccessor has to wait
143  m_WaitLock->m_Mutex.Lock();
144 
145  // insert self into Writers list in Image
146  m_Image->m_Writers.push_back(this);
147 
148  // printf("WriteAccess %d %d\n",(int) m_Image->m_Readers.size(),(int) m_Image->m_Writers.size());
149  // fflush(0);
150  m_Image->m_ReadWriteLock.Unlock();
151 }
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.
unsigned int m_WaiterCount
Holds the number of ImageAccessors, which are waiting until the represented ImageAccessor is released...
virtual ~ImageWriteAccessor()
informs Image to unlock the represented image part
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:76
#define mitkThrowException(classname)
int m_Options
Stores all extended properties of an ImageAccessor. The different flags in mitk::ImageAccessorBase::O...
This struct allows to make ImageAccessors wait for this particular ImageAccessor object.
Internal class for managing references on sub-images.
virtual const Image * GetImage() const override