Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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