itom
Loading...
Searching...
No Matches
sharedStructuresQt.h
1/* ********************************************************************
2 itom software
3 URL: http://www.uni-stuttgart.de/ito
4 Copyright (C) 2020, Institut für Technische Optik (ITO),
5 Universität Stuttgart, Germany
6
7 This file is part of itom and its software development toolkit (SDK).
8
9 itom is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Library General Public Licence as published by
11 the Free Software Foundation; either version 2 of the Licence, or (at
12 your option) any later version.
13
14 In addition, as a special exception, the Institut für Technische
15 Optik (ITO) gives you certain additional rights.
16 These rights are described in the ITO LGPL Exception version 1.0,
17 which can be found in the file LGPL_EXCEPTION.txt in this package.
18
19 itom is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
22 General Public Licence for more details.
23
24 You should have received a copy of the GNU Library General Public License
25 along with itom. If not, see <http://www.gnu.org/licenses/>.
26*********************************************************************** */
27
28#ifndef SHAREDSTRUCTURES_QT_H
29#define SHAREDSTRUCTURES_QT_H
30
31#include "commonGlobal.h"
32#include <qmutex.h>
33#include <qsemaphore.h>
34#include <qdebug.h>
35#include <qeventloop.h>
36#include <qmap.h>
37#include <qstring.h>
38
39#include "sharedStructures.h"
40
41//definition of some tags for signals and slots
42#ifndef Q_MOC_RUN
43 //the following tags can be placed before the definition of slots and signals, they are then obtainable via the tag() method of QMetaMethod.
44
45 //place ITOM_PYNOTACCESSIBLE before the definition of a method to not show this method in auto-parsed listings that are dedicated to python usage.
46 #define ITOM_PYNOTACCESSIBLE
47#endif
48
49#if !defined(Q_MOC_RUN) || defined(ITOMCOMMONQT_MOC) //only moc this file in itomCommonQtLib but not in other libraries or executables linking against this itomCommonQtLib
50
51typedef QMap<QString, ito::Param> ParamMap;
52typedef ParamMap::iterator ParamMapIterator;
53
54//namespace ito
55//{
56
57class ITOMCOMMONQT_EXPORT ItomSharedSemaphore
58{
59 private:
60 QSemaphore *m_pSemaphore;
67 public:
69
77 inline ItomSharedSemaphore(int numberOfListeners = 1) :
78 m_numOfListeners(numberOfListeners),
79 m_instCounter(numberOfListeners + 1),
80 m_enableDelete(false),
81 m_callerStillWaiting(true),
82 returnValue(ito::retOk)
83 {
84 QMutexLocker mutexLocker(&internalMutex);
85 m_pSemaphore = new QSemaphore(m_numOfListeners);
86 m_pSemaphore->acquire(m_numOfListeners);
87 }
88
90 /*
91 \sa ItomSharedSemaphore::deleteSemaphore
92 */
94 {
95 Q_ASSERT_X(m_enableDelete, "~ItomSharedSemaphore", "it is not allowed to directly destroy ItomSharedSemaphore. Always use ItomSharedSemaphore::deleteSemaphore(...)");
96
97 if(m_pSemaphore->available() < m_numOfListeners)
98 {
99 m_pSemaphore->release( m_numOfListeners - m_pSemaphore->available());
100 qDebug("ItomSharedSemaphore is not fully available at moment of destruction");
101 }
102 if (m_pSemaphore)
103 delete m_pSemaphore;
104 m_pSemaphore = NULL;
105 }
106
108 /*
109 The timeout time is indicated in milliseconds, a value equal to -1 means that no timeout is set and this methods
110 only returns if the called method released the semaphore. In the constructor of ItomSharedSemaphore, the semaphore
111 has been locked with a number equal to the number of listeners, which usually is 1. The semaphore is unlocked, if
112 every listener releases the semaphore once (\sa release).
113
114 A possible timeout is indicated by a debug-warning in the output window of the IDE.
115
116 @param [in] timeout in ms [-1 : no timeout]
117 @return true if caller (listener) released the lock within the given timeout time, false if timeout expired
118 @sa release, waitAndProcessEvents
119 */
120 inline bool wait(int timeout)
121 {
122 bool success;
123
124 if (timeout >= 0)
125 {
126 success = m_pSemaphore->tryAcquire(m_numOfListeners, timeout);
127 }
128 else
129 {
130 //due to a bug in linux (at least CentOS 7), tryAcquire causes a crash for infinite timeouts.
131 //therefore, we use the specific case here, to handle these cases.
132 m_pSemaphore->acquire(m_numOfListeners);
133 success = true;
134 }
135
136 QMutexLocker mutexLocker(&internalMutex);
137 if(success == false)
138 {
139 qDebug() << "ItomSharedSemaphore run into a timeout. Number of attempted listeners: " << m_numOfListeners << ", already freed: " << m_pSemaphore->available();
140 }
141 else
142 {
143 m_pSemaphore->release(m_numOfListeners);
144 }
145
146 m_callerStillWaiting = false;
147
148 return success;
149 }
150
152 /*
153 The timeout time is indicated in milliseconds, a value equal to -1 means that no timeout is set and this methods
154 only returns if the called method released the semaphore. In the constructor of ItomSharedSemaphore, the semaphore
155 has been locked with a number equal to the number of listeners, which usually is 1. The semaphore is unlocked, if
156 every listener releases the semaphore once (\sa release).
157
158 The only difference between this method and wait is, that this implementation continuously allows
159 processing events in the event loop of the waiting thread. The type of allowed events is set by flags.
160
161 A possible timeout is indicated by a debug-warning in the output window of the IDE.
162
163 @param [in] timeout in ms [-1 : no timeout]
164 @param [in] flags is the type of allowed events that can be processed in the calling thread during the wait.
165 @return true if caller (listener) released the lock within the given timeout time, false if timeout expired
166 @sa release, wait
167 */
168 bool waitAndProcessEvents(int timeout, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents);
169
171 /*
172 the called method in another thread must release the semaphore as soon as possible such that the caller can continue
173 */
174 inline void release() { /*qDebug() << "semaphore release";*/ m_pSemaphore->release(1); }
175
177 /*
178 @return true if semaphore is still locked, else false
179 */
180 inline int available() const { return m_pSemaphore->available(); }
181
183 /*
184 this method is not 100% thread-safe, that means it might occur, that the wait-method of the caller drops into the timeout
185 during the call to the method isCallerStillWaiting. Therefore consider this method as pure information.
186
187 @return true if caller-method is still waiting (in \sa wait-method) that all listeners are calling the release method
188 in order to free the lock of the semaphore. else: false
189 */
190 inline bool isCallerStillWaiting() { QMutexLocker mutexLocker(&internalMutex); return m_callerStillWaiting; }
191
193 //
194 // Every listener and the caller-method must call this static method with the pointer to the corresponding ItomSharedSemaphore
195 // in order to guarantee the final deletion of the semaphore, if it is not needed any more by any participating method (caller or listener).
196 //
197 // In every listener method (called method) you should call this method after you released the semaphore (\sa release).
198 // The ItomSharedSemaphore consists of a internal reference counter, which is set to the number of listeners plus 1 at
199 // construction time. Every call to deleteSemaphore decreases this counter and if this counter drops to zero, no method
200 // uses the semaphore any more such that it is safely deleted. Be careful that you don't access the semaphore in a method
201 // where you already called deleteSemaphore with the semaphore-pointer as parameter.
202 //
203 // In order to simplify the handling of ItomSharedSemaphore consider to used ItomSharedSemaphoreLocker.
204
205 inline void deleteSemaphore(void)
206 {
207 QMutexLocker mutexLocker(&internalMutex);
208
209 m_instCounter --;
210 if(m_instCounter <= 0)
211 {
212 m_enableDelete = true;
213 mutexLocker.unlock();
214 delete this;
215 return;
216 }
217
218 return;
219 }
220
222};
223
224
233{
234 public:
237
240
243 {
244 if(m_semaphore)
245 {
247 m_semaphore = NULL;
248 }
249 }
250
252 inline ItomSharedSemaphore* getSemaphore() const { return m_semaphore; }
253
256
258 /*
259 If this locker already guards an instance of ItomSharedSemaphore its reference counter is decremented first. \sa ItomSharedSemaphore::deleteSemaphore.
260 */
262 {
263 if(m_semaphore)
264 {
266 m_semaphore = NULL;
267 }
268 m_semaphore = newSemaphoreInstance;
269 return *this;
270 }
271
272 private:
273 inline ItomSharedSemaphoreLocker(ItomSharedSemaphoreLocker & /*other*/ ) { /* forbidden */ }
274 inline ItomSharedSemaphoreLocker & operator = (const ItomSharedSemaphoreLocker & /*other*/ ) { return *this; /* forbidden */ }
276};
277
278//} //end namespace ito
279
280#endif //#if !defined(Q_MOC_RUN) || defined(ITOMCOMMONQT_MOC)
281
282#endif
semaphore which can be used for asynchronous thread communication. By using this class it is possible...
Definition sharedStructuresQt.h:58
ItomSharedSemaphore(int numberOfListeners=1)
constructor
Definition sharedStructuresQt.h:77
bool m_callerStillWaiting
Definition sharedStructuresQt.h:64
~ItomSharedSemaphore()
destructor (do not call directly, instead free the semaphore by ItomSharedSemaphore::deleteSemaphore
Definition sharedStructuresQt.h:93
bool m_enableDelete
Definition sharedStructuresQt.h:62
void release()
decreases the number of locks by one
Definition sharedStructuresQt.h:174
QMutex internalMutex
Definition sharedStructuresQt.h:65
bool wait(int timeout)
The call of this method returns if a certain timeout has been expired or every listener released the ...
Definition sharedStructuresQt.h:120
int m_numOfListeners
Definition sharedStructuresQt.h:63
int available() const
checks whether the semaphore is still locked or not
Definition sharedStructuresQt.h:180
int m_instCounter
Definition sharedStructuresQt.h:61
ito::RetVal returnValue
Definition sharedStructuresQt.h:221
bool isCallerStillWaiting()
indicates whether caller-method is still waiting that the lock is released by the listener(s).
Definition sharedStructuresQt.h:190
void deleteSemaphore(void)
static method to decrease the reference counter of any ItomSharedSemaphore or delete it if the refere...
Definition sharedStructuresQt.h:205
QSemaphore * m_pSemaphore
Definition sharedStructuresQt.h:60
Locker-class for ItomSharedSemaphore. The functionality is equal to QMutexLocker in Qt....
Definition sharedStructuresQt.h:233
ItomSharedSemaphoreLocker()
empty constructor. The locker will not guard any semaphore yet.
Definition sharedStructuresQt.h:239
ItomSharedSemaphoreLocker & operator=(ItomSharedSemaphore *newSemaphoreInstance)
assigns another ItomSharedSemaphore to this locker.
Definition sharedStructuresQt.h:261
ItomSharedSemaphoreLocker(ItomSharedSemaphore *semaphore)
constructor with ItomSharedSemaphore-pointer as parameter. This semaphore will be guarded by this loc...
Definition sharedStructuresQt.h:236
ItomSharedSemaphore * getSemaphore() const
returns the pointer to the guarded ItomSharedSemaphore.
Definition sharedStructuresQt.h:252
ItomSharedSemaphore * operator->() const
returns the pointer to the guarded ItomSharedSemaphore.
Definition sharedStructuresQt.h:255
ItomSharedSemaphore * m_semaphore
Definition sharedStructuresQt.h:275
~ItomSharedSemaphoreLocker()
destructor.
Definition sharedStructuresQt.h:242
Class for managing status values (like errors or warning)
Definition retVal.h:54
Definition apiFunctionsGraph.cpp:40