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
mitkImageReadAccessor.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 "mitkImageReadAccessor.h"
18 
19 #include "mitkImage.h"
20 
22  : ImageAccessorBase(image, iDI, OptionFlags), m_Image(image)
23 {
24  if (!(OptionFlags & ImageAccessorBase::IgnoreLock))
25  {
26  try
27  {
28  OrganizeReadAccess();
29  }
30  catch (...)
31  {
32  delete m_WaitLock;
33  throw;
34  }
35  }
36 }
37 
39  : ImageAccessorBase(image.GetPointer(), iDI, OptionFlags), m_Image(image.GetPointer())
40 {
41  if (!(OptionFlags & ImageAccessorBase::IgnoreLock))
42  {
43  try
44  {
45  OrganizeReadAccess();
46  }
47  catch (...)
48  {
49  delete m_WaitLock;
50  throw;
51  }
52  }
53 }
54 
56  : ImageAccessorBase(image, iDI, ImageAccessorBase::DefaultBehavior), m_Image(image)
57 {
58  OrganizeReadAccess();
59 }
60 
62 {
63  if (!(m_Options & ImageAccessorBase::IgnoreLock))
64  {
65  // Future work: In case of non-coherent memory, copied area needs to be deleted
66 
67  m_Image->m_ReadWriteLock.Lock();
68 
69  // delete self from list of ImageReadAccessors in Image
70  auto it = std::find(m_Image->m_Readers.begin(), m_Image->m_Readers.end(), this);
71  m_Image->m_Readers.erase(it);
72 
73  // delete lock, if there are no waiting ImageAccessors
74  if (m_WaitLock->m_WaiterCount <= 0)
75  {
76  m_WaitLock->m_Mutex.Unlock();
77  delete m_WaitLock;
78  }
79  else
80  {
81  m_WaitLock->m_Mutex.Unlock();
82  }
83 
84  m_Image->m_ReadWriteLock.Unlock();
85  }
86  else
87  {
88  delete m_WaitLock;
89  }
90 }
91 
93 {
94  return m_Image.GetPointer();
95 }
96 
97 void mitk::ImageReadAccessor::OrganizeReadAccess()
98 {
99  m_Image->m_ReadWriteLock.Lock();
100 
101  // Check, if there is any Write-Access going on
102  if (m_Image->m_Writers.size() > 0)
103  {
104  // Check for every WriteAccessors, if the Region of this ImageAccessors overlaps
105  // make sure this iterator is not used, when m_ReadWriteLock is Unlocked!
106  auto it = m_Image->m_Writers.begin();
107 
108  for (; it != m_Image->m_Writers.end(); ++it)
109  {
110  ImageAccessorBase *w = *it;
111  if (Overlap(w))
112  {
113  // An Overlap was detected. There are two possibilities to deal with this situation:
114  // Throw an exception or wait for the WriteAccessor w until it is released and start again with the request
115  // afterwards.
116  if (!(m_Options & ExceptionIfLocked))
117  {
118  PreventRecursiveMutexLock(w);
119 
120  // WAIT
121  w->Increment();
122  m_Image->m_ReadWriteLock.Unlock();
124 
125  // after waiting for the WriteAccessor w, start this method again
126  OrganizeReadAccess();
127  return;
128  }
129  else
130  {
131  // THROW EXCEPTION
132  m_Image->m_ReadWriteLock.Unlock();
134  << "The image part being ordered by the ImageAccessor is already in use and locked";
135  return;
136  }
137  } // if
138  } // for
139  } // if
140 
141  // Now, we know, that there is no conflict with a Write-Access
142  // Lock the Mutex in ImageAccessorBase, to make sure that every other ImageAccessor has to wait if it locks the mutex
143  m_WaitLock->m_Mutex.Lock();
144 
145  // insert self into readers list in Image
146  m_Image->m_Readers.push_back(this);
147 
148  // printf("ReadAccess %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 }
virtual const Image * GetImage() const override
void WaitForReleaseOf(ImageAccessorWaitLock *wL)
Uses the WaitLock to wait for another ImageAccessor.
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
ImageReadAccessor(ImageConstPointer image, const ImageDataItem *iDI=nullptr, int OptionFlags=ImageAccessorBase::DefaultBehavior)
Orders read access for a slice, volume or 4D-Image.
void Increment()
Increments m_WaiterCount. A call of this method is prohibited unless the Mutex m_ReadWriteLock in the...
#define mitkThrowException(classname)
Internal class for managing references on sub-images.