Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:59

0001 // Created on: 2005-04-10
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2005-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _Standard_Mutex_HeaderFile
0017 #define _Standard_Mutex_HeaderFile
0018 
0019 #include <Standard_Integer.hxx>
0020 #include <Standard_Boolean.hxx>
0021 #include <Standard_ErrorHandler.hxx>
0022 #include <NCollection_Shared.hxx>
0023 
0024 #if defined(_WIN32)
0025   #include <windows.h>
0026 #else
0027   #include <pthread.h>
0028   #include <unistd.h>
0029   #include <time.h>
0030 #endif
0031 
0032 /** 
0033   * @brief Mutex: a class to synchronize access to shared data. 
0034   *
0035   * This is simple encapsulation of tools provided by the
0036   * operating system to synchronize access to shared data
0037   * from threads within one process.
0038   *
0039   * Current implementation is very simple and straightforward;
0040   * it is just a wrapper around POSIX pthread library on UNIX/Linux,
0041   * and CRITICAL_SECTIONs on Windows NT. It does not provide any
0042   * advanced functionality such as recursive calls to the same mutex from
0043   * within one thread (such call will freeze the execution).
0044   *
0045   * Note that all the methods of that class are made inline, in order
0046   * to keep maximal performance. This means that a library using the mutex
0047   * might need to be linked to threads library directly.
0048   *
0049   * The typical use of this class should be as follows:
0050   * - create instance of the class Standard_Mutex in the global scope
0051   *   (whenever possible, or as a field of your class)
0052   * - create instance of class Standard_Mutex::Sentry using that Mutex
0053   *   when entering critical section
0054   *
0055   * Note that this class provides one feature specific to Open CASCADE:
0056   * safe unlocking the mutex when signal is raised and converted to OCC
0057   * exceptions (Note that with current implementation of this functionality
0058   * on UNIX and Linux, C longjumps are used for that, thus destructors of 
0059   * classes are not called automatically).
0060   * 
0061   * To use this feature, call RegisterCallback() after Lock() or successful
0062   * TryLock(), and UnregisterCallback() before Unlock() (or use Sentry classes). 
0063   */
0064 
0065 class Standard_Mutex : public Standard_ErrorHandler::Callback
0066 {
0067 public:
0068   /**
0069     * @brief Simple sentry class providing convenient interface to mutex.
0070     * 
0071     * Provides automatic locking and unlocking a mutex in its constructor
0072     * and destructor, thus ensuring correct unlock of the mutex even in case of 
0073     * raising an exception or signal from the protected code.
0074     *
0075     * Create instance of that class when entering critical section.
0076     */
0077   class Sentry 
0078   {
0079   public:
0080 
0081     //! Constructor - initializes the sentry object by reference to a
0082     //! mutex (which must be initialized) and locks the mutex immediately
0083     Sentry (Standard_Mutex& theMutex)
0084     : myMutex (&theMutex)
0085     {
0086       Lock();
0087     }
0088     
0089     //! Constructor - initializes the sentry object by pointer to a
0090     //! mutex and locks the mutex if its pointer is not NULL
0091     Sentry (Standard_Mutex* theMutex)
0092     : myMutex (theMutex)
0093     {
0094       if (myMutex != NULL)
0095       {
0096         Lock();
0097       }
0098     }
0099     //! Destructor - unlocks the mutex if already locked.
0100     ~Sentry()
0101     {
0102       if (myMutex != NULL)
0103       {
0104         Unlock();
0105       }
0106     }
0107 
0108   private:
0109 
0110     //! Lock the mutex
0111     void Lock()
0112     {
0113       myMutex->Lock();
0114       myMutex->RegisterCallback();
0115     }
0116 
0117     //! Unlock the mutex
0118     void Unlock()
0119     {
0120       myMutex->UnregisterCallback();
0121       myMutex->Unlock();
0122     }
0123 
0124     //! This method should not be called (prohibited).
0125     Sentry (const Sentry &);
0126     //! This method should not be called (prohibited).
0127     Sentry& operator = (const Sentry &);
0128 
0129   private:
0130     Standard_Mutex* myMutex;
0131   };
0132    
0133 public:
0134   
0135   //! Constructor: creates a mutex object and initializes it.
0136   //! It is strongly recommended that mutexes were created as 
0137   //! static objects whenever possible.
0138   Standard_EXPORT Standard_Mutex ();
0139   
0140   //! Destructor: destroys the mutex object
0141   Standard_EXPORT ~Standard_Mutex ();
0142   
0143   //! Method to lock the mutex; waits until the mutex is released
0144   //! by other threads, locks it and then returns
0145   Standard_EXPORT void Lock ();
0146 
0147   //! Method to test the mutex; if the mutex is not hold by other thread,
0148   //! locks it and returns True; otherwise returns False without waiting
0149   //! mutex to be released.
0150   Standard_EXPORT Standard_Boolean TryLock ();
0151 
0152   //! Method to unlock the mutex; releases it to other users
0153   void Unlock ();
0154 
0155 private:
0156 
0157   //! Callback method to unlock the mutex if OCC exception or signal is raised
0158   Standard_EXPORT virtual void DestroyCallback() Standard_OVERRIDE;
0159   
0160   //! This method should not be called (prohibited).
0161   Standard_Mutex (const Standard_Mutex &);
0162   //! This method should not be called (prohibited).
0163   Standard_Mutex& operator = (const Standard_Mutex &);
0164   
0165 private:
0166 #if (defined(_WIN32) || defined(__WIN32__))
0167   CRITICAL_SECTION myMutex;
0168 #else
0169   pthread_mutex_t myMutex;
0170 #endif  
0171 };
0172 
0173 typedef NCollection_Shared<Standard_Mutex> Standard_HMutex;
0174 
0175 // Implementation of the method Unlock is inline, since it is 
0176 // just a shortcut to system function
0177 inline void Standard_Mutex::Unlock ()
0178 {
0179 #if (defined(_WIN32) || defined(__WIN32__))
0180   LeaveCriticalSection (&myMutex);
0181 #else
0182   pthread_mutex_unlock (&myMutex);
0183 #endif
0184 }
0185 
0186 #endif /* _Standard_Mutex_HeaderFile */