GCSynch.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. //-----------------------------------------------------------------------------
  2. // (c) 2006 by Basler Vision Technologies
  3. // Section: Vision Components
  4. // Project: GenApi
  5. // Author: Hartmut Nebelung
  6. // $Header$
  7. //
  8. // License: This file is published under the license of the EMVA GenICam Standard Group.
  9. // A text file describing the legal terms is included in your installation as 'GenICam_license.pdf'.
  10. // If for some reason you are missing this file please contact the EMVA or visit the website
  11. // (http://www.genicam.org) for a full copy.
  12. //
  13. // THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
  14. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD GROUP
  17. // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  20. // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  21. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  23. // POSSIBILITY OF SUCH DAMAGE.
  24. //-----------------------------------------------------------------------------
  25. /*!
  26. \file
  27. \brief Definition of Lock classes
  28. \ingroup Base_PublicUtilities
  29. */
  30. #ifndef GENAPI_GCSYNCH_H
  31. #define GENAPI_GCSYNCH_H
  32. #include <Base/GCTypes.h>
  33. #include <Base/GCException.h>
  34. #if defined (_WIN32)
  35. # include <windows.h>
  36. # include <winbase.h>
  37. #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
  38. # include <semaphore.h>
  39. # include <pthread.h>
  40. # include <errno.h>
  41. # include <list>
  42. #elif defined(VXWORKS)
  43. #include <vxworks.h>
  44. #include <taskLib.h>
  45. #else
  46. # error No/unknown platform thread support
  47. #endif
  48. namespace GENICAM_NAMESPACE
  49. {
  50. //-----------------------------------------------------------------
  51. // CLock
  52. //-----------------------------------------------------------------
  53. /**
  54. \brief A lock class
  55. \ingroup Base_PublicUtilities
  56. */
  57. class GCBASE_API CLock
  58. {
  59. public:
  60. //! Constructor
  61. CLock();
  62. //! Destructor
  63. ~CLock();
  64. //! tries to enter the critical section; returns true if successful
  65. bool TryLock();
  66. //! enters the critical section (may block)
  67. void Lock();
  68. //! leaves the critical section
  69. void Unlock();
  70. private:
  71. //! no copy constructor
  72. CLock( const CLock& );
  73. //! no assignment operator
  74. CLock& operator=( const CLock& );
  75. protected:
  76. #if defined (_WIN32)
  77. //! The critical section object
  78. CRITICAL_SECTION m_csObject;
  79. #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
  80. //! the mutex object
  81. pthread_mutex_t m_mtxObject;
  82. #elif defined(VXWORKS)
  83. SEM_ID m_sem;
  84. #else
  85. # error No/unknown platform thread support
  86. #endif
  87. };
  88. //! This class is for testing purposes only. It should not be used for
  89. //! client code because it exists only for Windows but not for Linux
  90. //! since it uses internal data structures of a Win32 object
  91. class GCBASE_API CLockEx : public CLock
  92. {
  93. public:
  94. # if defined (_WIN32)
  95. //! Gives access to internal data member for test and purposes
  96. int64_t GetLockCount();
  97. //! Gives access to internal data member for test and purposes
  98. int64_t GetRecursionCount();
  99. # elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__) || defined(VXWORKS))
  100. // nothing implemented for Unix
  101. # else
  102. # error No/unknown platform support
  103. # endif
  104. private:
  105. //! no copy constructor
  106. CLockEx( const CLockEx& );
  107. //! no assignment operator
  108. CLockEx& operator=( const CLockEx& );
  109. };
  110. //-----------------------------------------------------------------
  111. // AutoLock
  112. //-----------------------------------------------------------------
  113. class AutoLock
  114. {
  115. CLock& m_Lock;
  116. public:
  117. AutoLock(CLock& lock)
  118. : m_Lock(lock)
  119. {
  120. m_Lock.Lock();
  121. }
  122. ~AutoLock()
  123. {
  124. m_Lock.Unlock();
  125. }
  126. private:
  127. AutoLock& operator=(const AutoLock&);
  128. AutoLock(const AutoLock&);
  129. };
  130. //-----------------------------------------------------------------
  131. // template LockableObject<Object,ThreadingModel>
  132. //-----------------------------------------------------------------
  133. /**
  134. \brief Instance-Lock for an object
  135. \ingroup Base_PublicUtilities
  136. */
  137. template< class Object>
  138. class LockableObject
  139. {
  140. public:
  141. mutable CLock m_Lock;
  142. class Lock;
  143. friend class Lock;
  144. /*! A scopelevel Lock class.
  145. * Automatically acquires the lock when created and releases
  146. * it when destroyed.
  147. */
  148. class Lock
  149. {
  150. /// Reference to outer object
  151. const LockableObject<Object> &m_Object;
  152. public:
  153. Lock( const LockableObject<Object>& obj) : m_Object(obj) {
  154. m_Object.m_Lock.Lock();
  155. }
  156. ~Lock(){
  157. m_Object.m_Lock.Unlock();
  158. }
  159. private:
  160. Lock& operator=( const Lock& );
  161. };
  162. /// Get a new lock
  163. Lock GetLock() const
  164. {
  165. return Lock( *this );
  166. }
  167. };
  168. /**
  169. \brief Named global lock which can be used over process boundaries
  170. \ingroup Base_PublicUtilities
  171. */
  172. class GCBASE_API CGlobalLock
  173. {
  174. public:
  175. //! Creates a global lock object name pszName.
  176. //! In case an object with the same name already exists
  177. //! a reference to the existing object will be created.
  178. //! If pszName is NULL an unnamed object will be created.
  179. explicit CGlobalLock(const char* pszName);
  180. #if defined(_WIN32) && ! defined(PHARLAP_WIN32)
  181. //! Creates a global lock object name pszName.
  182. //! In case an object with the same name already exists
  183. //! a reference to the existing object will be created.
  184. //! If pszName is NULL an unnamed object will be created.
  185. explicit CGlobalLock(const wchar_t* pszName);
  186. #endif
  187. //! Creates a global lock object name strName.
  188. //! In case an object with the same name already exists
  189. //! a reference to the existing object will be created.
  190. //! If strName is empty an unnamed object will be created.
  191. explicit CGlobalLock(const GENICAM_NAMESPACE::gcstring& strName);
  192. ~CGlobalLock();
  193. public:
  194. //! tests whether the lock is valid
  195. bool IsValid(void) const;
  196. //! enters the lock (may block)
  197. bool Lock(unsigned int timeout_ms);
  198. //! tries to enter the lock and returns immediately when not possible
  199. bool TryLock(void);
  200. //! leaves the lock
  201. void Unlock(void);
  202. #if defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
  203. // creates a hashed name instead of the real name
  204. void HashSemName(const GENICAM_NAMESPACE::gcstring& strName);
  205. #endif
  206. protected:
  207. #if defined(_WIN32)
  208. HANDLE m_handle;
  209. #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
  210. GENICAM_NAMESPACE::gcstring m_semName;
  211. sem_t* m_handle;
  212. #elif VXWORKS
  213. // There are no named locks on VxWorks. While we could use a single global lock, we
  214. // will just rely on the caller to add their own locking in
  215. #else
  216. # error No/unknown platform thread support
  217. #endif
  218. // This is for debugging/assertions only
  219. // the d'tor check whether this is 0 in debug builds
  220. // in release builds this is always 0
  221. mutable long m_DebugCount;
  222. private:
  223. // not copyable
  224. CGlobalLock(const CGlobalLock&);
  225. CGlobalLock& operator=(const CGlobalLock&);
  226. };
  227. /**
  228. \brief unlocks the global lock object on destruction
  229. This is for automatic UNLOCKING only.
  230. We can't do automatic locking here since there is no returnvalue for contructors
  231. \ingroup Base_PublicUtilities
  232. */
  233. //-----------------------------------------------------------------
  234. // unlocks the global lock object on destruction
  235. // this is for automatic UNLOCKING only.
  236. // we can't do automatic locking here since we don't get a returnvalue from the c'tor
  237. //-----------------------------------------------------------------
  238. class GCBASE_API CGlobalLockUnlocker
  239. {
  240. protected:
  241. CGlobalLock& m_Lock;
  242. bool m_enabled;
  243. public:
  244. CGlobalLockUnlocker(CGlobalLock& lock)
  245. : m_Lock(lock)
  246. , m_enabled(true) // this allows the auto unlock to be turned off for messy code structures
  247. {
  248. // explicitly don't lock the object here since we want to do this manually and handle the return value properly
  249. }
  250. ~CGlobalLockUnlocker()
  251. {
  252. UnlockEarly();
  253. }
  254. //! This function allows to unlock the object early before the object is destroyed
  255. void UnlockEarly(void)
  256. {
  257. if (m_enabled)
  258. {
  259. m_enabled = false;
  260. m_Lock.Unlock();
  261. }
  262. }
  263. private:
  264. CGlobalLockUnlocker& operator=(const CGlobalLockUnlocker&);
  265. CGlobalLockUnlocker(const CGlobalLockUnlocker&);
  266. };
  267. } // namespace GenICam
  268. #endif // GENAPI_GCSYNCH_H