123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- //-----------------------------------------------------------------------------
- // (c) 2006 by Basler Vision Technologies
- // Section: Vision Components
- // Project: GenApi
- // Author: Hartmut Nebelung
- // $Header$
- //
- // License: This file is published under the license of the EMVA GenICam Standard Group.
- // A text file describing the legal terms is included in your installation as 'GenICam_license.pdf'.
- // If for some reason you are missing this file please contact the EMVA or visit the website
- // (http://www.genicam.org) for a full copy.
- //
- // THIS SOFTWARE IS PROVIDED BY THE EMVA GENICAM STANDARD GROUP "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE EMVA GENICAM STANDARD GROUP
- // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //-----------------------------------------------------------------------------
- /*!
- \file
- \brief Definition of Lock classes
- \ingroup Base_PublicUtilities
- */
- #ifndef GENAPI_GCSYNCH_H
- #define GENAPI_GCSYNCH_H
- #include <Base/GCTypes.h>
- #include <Base/GCException.h>
- #if defined (_WIN32)
- # include <windows.h>
- # include <winbase.h>
- #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
- # include <semaphore.h>
- # include <pthread.h>
- # include <errno.h>
- # include <list>
- #elif defined(VXWORKS)
- #include <vxworks.h>
- #include <taskLib.h>
- #else
- # error No/unknown platform thread support
- #endif
- namespace GENICAM_NAMESPACE
- {
- //-----------------------------------------------------------------
- // CLock
- //-----------------------------------------------------------------
- /**
- \brief A lock class
- \ingroup Base_PublicUtilities
- */
- class GCBASE_API CLock
- {
- public:
- //! Constructor
- CLock();
- //! Destructor
- ~CLock();
- //! tries to enter the critical section; returns true if successful
- bool TryLock();
- //! enters the critical section (may block)
- void Lock();
- //! leaves the critical section
- void Unlock();
- private:
- //! no copy constructor
- CLock( const CLock& );
- //! no assignment operator
- CLock& operator=( const CLock& );
- protected:
- #if defined (_WIN32)
- //! The critical section object
- CRITICAL_SECTION m_csObject;
- #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
- //! the mutex object
- pthread_mutex_t m_mtxObject;
- #elif defined(VXWORKS)
- SEM_ID m_sem;
- #else
- # error No/unknown platform thread support
- #endif
- };
- //! This class is for testing purposes only. It should not be used for
- //! client code because it exists only for Windows but not for Linux
- //! since it uses internal data structures of a Win32 object
- class GCBASE_API CLockEx : public CLock
- {
- public:
- # if defined (_WIN32)
- //! Gives access to internal data member for test and purposes
- int64_t GetLockCount();
- //! Gives access to internal data member for test and purposes
- int64_t GetRecursionCount();
- # elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__) || defined(VXWORKS))
- // nothing implemented for Unix
- # else
- # error No/unknown platform support
- # endif
- private:
- //! no copy constructor
- CLockEx( const CLockEx& );
- //! no assignment operator
- CLockEx& operator=( const CLockEx& );
- };
- //-----------------------------------------------------------------
- // AutoLock
- //-----------------------------------------------------------------
- class AutoLock
- {
- CLock& m_Lock;
- public:
- AutoLock(CLock& lock)
- : m_Lock(lock)
- {
- m_Lock.Lock();
- }
- ~AutoLock()
- {
- m_Lock.Unlock();
- }
- private:
- AutoLock& operator=(const AutoLock&);
- AutoLock(const AutoLock&);
- };
- //-----------------------------------------------------------------
- // template LockableObject<Object,ThreadingModel>
- //-----------------------------------------------------------------
- /**
- \brief Instance-Lock for an object
- \ingroup Base_PublicUtilities
- */
- template< class Object>
- class LockableObject
- {
- public:
- mutable CLock m_Lock;
- class Lock;
- friend class Lock;
- /*! A scopelevel Lock class.
- * Automatically acquires the lock when created and releases
- * it when destroyed.
- */
- class Lock
- {
- /// Reference to outer object
- const LockableObject<Object> &m_Object;
- public:
- Lock( const LockableObject<Object>& obj) : m_Object(obj) {
- m_Object.m_Lock.Lock();
- }
- ~Lock(){
- m_Object.m_Lock.Unlock();
- }
- private:
- Lock& operator=( const Lock& );
- };
- /// Get a new lock
- Lock GetLock() const
- {
- return Lock( *this );
- }
- };
- /**
- \brief Named global lock which can be used over process boundaries
- \ingroup Base_PublicUtilities
- */
- class GCBASE_API CGlobalLock
- {
- public:
- //! Creates a global lock object name pszName.
- //! In case an object with the same name already exists
- //! a reference to the existing object will be created.
- //! If pszName is NULL an unnamed object will be created.
- explicit CGlobalLock(const char* pszName);
- #if defined(_WIN32) && ! defined(PHARLAP_WIN32)
- //! Creates a global lock object name pszName.
- //! In case an object with the same name already exists
- //! a reference to the existing object will be created.
- //! If pszName is NULL an unnamed object will be created.
- explicit CGlobalLock(const wchar_t* pszName);
- #endif
- //! Creates a global lock object name strName.
- //! In case an object with the same name already exists
- //! a reference to the existing object will be created.
- //! If strName is empty an unnamed object will be created.
- explicit CGlobalLock(const GENICAM_NAMESPACE::gcstring& strName);
- ~CGlobalLock();
- public:
- //! tests whether the lock is valid
- bool IsValid(void) const;
- //! enters the lock (may block)
- bool Lock(unsigned int timeout_ms);
- //! tries to enter the lock and returns immediately when not possible
- bool TryLock(void);
- //! leaves the lock
- void Unlock(void);
- #if defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
- // creates a hashed name instead of the real name
- void HashSemName(const GENICAM_NAMESPACE::gcstring& strName);
- #endif
- protected:
- #if defined(_WIN32)
- HANDLE m_handle;
- #elif defined (__GNUC__) && (defined (__linux__) || defined (__APPLE__))
- GENICAM_NAMESPACE::gcstring m_semName;
- sem_t* m_handle;
- #elif VXWORKS
- // There are no named locks on VxWorks. While we could use a single global lock, we
- // will just rely on the caller to add their own locking in
- #else
- # error No/unknown platform thread support
- #endif
- // This is for debugging/assertions only
- // the d'tor check whether this is 0 in debug builds
- // in release builds this is always 0
- mutable long m_DebugCount;
- private:
- // not copyable
- CGlobalLock(const CGlobalLock&);
- CGlobalLock& operator=(const CGlobalLock&);
- };
- /**
- \brief unlocks the global lock object on destruction
- This is for automatic UNLOCKING only.
- We can't do automatic locking here since there is no returnvalue for contructors
- \ingroup Base_PublicUtilities
- */
- //-----------------------------------------------------------------
- // unlocks the global lock object on destruction
- // this is for automatic UNLOCKING only.
- // we can't do automatic locking here since we don't get a returnvalue from the c'tor
- //-----------------------------------------------------------------
- class GCBASE_API CGlobalLockUnlocker
- {
- protected:
- CGlobalLock& m_Lock;
- bool m_enabled;
- public:
- CGlobalLockUnlocker(CGlobalLock& lock)
- : m_Lock(lock)
- , m_enabled(true) // this allows the auto unlock to be turned off for messy code structures
- {
- // explicitly don't lock the object here since we want to do this manually and handle the return value properly
- }
- ~CGlobalLockUnlocker()
- {
- UnlockEarly();
- }
- //! This function allows to unlock the object early before the object is destroyed
- void UnlockEarly(void)
- {
- if (m_enabled)
- {
- m_enabled = false;
- m_Lock.Unlock();
- }
- }
- private:
- CGlobalLockUnlocker& operator=(const CGlobalLockUnlocker&);
- CGlobalLockUnlocker(const CGlobalLockUnlocker&);
- };
- } // namespace GenICam
- #endif // GENAPI_GCSYNCH_H
|