1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-16 10:54:53 +03:00

0023286: Standard_Mutex behavior depends on platform

Implemented recursive POSIX mutex instead of non-recursive,
Removed SentryNested class, implemented it's features into Sentry class
Added second constructor to Sentry class
This commit is contained in:
omy 2012-11-16 13:14:25 +04:00
parent 581971fef3
commit 49f38e37fc
4 changed files with 70 additions and 106 deletions

View File

@ -57,8 +57,6 @@
#define UVDEFLECTION 1.e-05
static Standard_Mutex DummyMutex;
static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
{
Standard_Integer i, j, n = 0;
@ -363,8 +361,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation
{
// lock mutex during querying data from edge curves to prevent parallel change of the same data
Standard_Mutex* aMutex = theMutexProvider.GetMutex(theEdge);
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
aMutex != NULL);
Standard_Mutex::Sentry aSentry (aMutex);
Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
if (Poly.IsNull() || !Poly->HasParameters())
@ -1636,8 +1633,7 @@ void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
// lock mutex to prevent parallel change of the same data
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
aMutex != NULL);
Standard_Mutex::Sentry aSentry (aMutex);
if ( NOD1 == NOD2 ) {
B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc);

View File

@ -394,7 +394,7 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize)
// and lock the specific mutex used to protect access to small blocks pools;
// note that this is done by sentry class so as to ensure unlocking in case of
// possible exception that may be thrown from AllocMemory()
Standard_Mutex::SentryNested aSentry ( myMutexPools, myReentrant );
Standard_Mutex::Sentry aSentry (myReentrant ? &myMutexPools : NULL);
// check for availability of requested space in the current pool
Standard_Size *aBlock = myNextAddr;
@ -533,7 +533,7 @@ void Standard_MMgrOpt::Free(Standard_Address& theStorage)
Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean )//isDeleted)
{
// Lock access to critical data by mutex
Standard_Mutex::SentryNested aSentry (myMutex, myReentrant);
Standard_Mutex::Sentry aSentry (myReentrant ? &myMutex : NULL);
// TODO: implement support for isDeleted = True
@ -553,7 +553,7 @@ Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean )//isDeleted)
}
// Lock access to critical data by mutex
Standard_Mutex::SentryNested aSentry1 ( myMutexPools, myReentrant );
Standard_Mutex::Sentry aSentry1 (myReentrant ? &myMutexPools : NULL);
// release memory pools containing no busy memory;
// for that for each pool count the summary size of blocks
@ -696,7 +696,7 @@ Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean )//isDeleted)
void Standard_MMgrOpt::FreePools()
{
// Lock access to critical data by mutex
Standard_Mutex::SentryNested aSentry ( myMutexPools, myReentrant );
Standard_Mutex::Sentry aSentry (myReentrant ? &myMutexPools : NULL);
// last pool is remembered in myAllocList
Standard_Size * aFree = myAllocList;

View File

@ -22,8 +22,8 @@
// and is surrounded by #ifdef in MS VC++ 7.1 headers.
// Thus to use it we need to define appropriate macro saying that we wil
// run on Windows NT 4.0 at least
#if defined(WNT) && ! defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
#define _WIN32_WINNT 0x0400
#endif
#include <Standard_Mutex.hxx>
@ -35,10 +35,14 @@
Standard_Mutex::Standard_Mutex ()
{
#ifdef WNT
InitializeCriticalSection( &myMutex );
#if (defined(_WIN32) || defined(__WIN32__))
InitializeCriticalSection (&myMutex);
#else
pthread_mutex_init( &myMutex, 0 );
pthread_mutexattr_t anAttr;
pthread_mutexattr_init (&anAttr);
pthread_mutexattr_settype (&anAttr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&myMutex, &anAttr);
pthread_mutexattr_destroy (&anAttr);
#endif
}
@ -48,10 +52,10 @@ Standard_Mutex::Standard_Mutex ()
Standard_Mutex::~Standard_Mutex ()
{
#ifdef WNT
DeleteCriticalSection( &myMutex );
#if (defined(_WIN32) || defined(__WIN32__))
DeleteCriticalSection (&myMutex);
#else
pthread_mutex_destroy( &myMutex );
pthread_mutex_destroy (&myMutex);
#endif
}
@ -61,10 +65,10 @@ Standard_Mutex::~Standard_Mutex ()
void Standard_Mutex::Lock ()
{
#ifdef WNT
EnterCriticalSection( &myMutex );
#if (defined(_WIN32) || defined(__WIN32__))
EnterCriticalSection (&myMutex);
#else
pthread_mutex_lock( &myMutex );
pthread_mutex_lock (&myMutex);
#endif
}
@ -74,10 +78,10 @@ void Standard_Mutex::Lock ()
Standard_Boolean Standard_Mutex::TryLock ()
{
#ifdef WNT
return ( TryEnterCriticalSection( &myMutex ) != 0 );
#if (defined(_WIN32) || defined(__WIN32__))
return (TryEnterCriticalSection (&myMutex) != 0);
#else
return ( pthread_mutex_trylock( &myMutex ) != EBUSY );
return (pthread_mutex_trylock (&myMutex) != EBUSY);
#endif
}

View File

@ -25,13 +25,13 @@
#include <Standard_Boolean.hxx>
#include <Standard_ErrorHandlerCallback.hxx>
#ifdef WNT
#include <windows.h>
#if (defined(_WIN32) || defined(__WIN32__))
#include <windows.h>
#else
#include <pthread.h>
#include <sys/errno.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <sys/errno.h>
#include <unistd.h>
#include <time.h>
#endif
/**
@ -85,92 +85,56 @@ public:
//! Constructor - initializes the sentry object by reference to a
//! mutex (which must be initialized) and locks the mutex immediately
Sentry (Standard_Mutex &theMutex)
: myMutex(theMutex)
Sentry (Standard_Mutex& theMutex)
: myMutex (&theMutex)
{
myMutex.Lock();
myMutex.RegisterCallback();
Lock();
}
//! Constructor - initializes the sentry object by pointer to a
//! mutex and locks the mutex if its pointer is not NULL
Sentry (Standard_Mutex* theMutex)
: myMutex (theMutex)
{
if (myMutex != NULL)
{
Lock();
}
}
//! Destructor - unlocks the mutex if already locked.
~Sentry () {
myMutex.UnregisterCallback();
myMutex.Unlock();
~Sentry()
{
if (myMutex != NULL)
{
Unlock();
}
}
private:
//! Lock the mutex
void Lock()
{
myMutex->Lock();
myMutex->RegisterCallback();
}
//! Unlock the mutex
void Unlock()
{
myMutex->UnregisterCallback();
myMutex->Unlock();
}
//! This method should not be called (prohibited).
Sentry (const Sentry &);
//! This method should not be called (prohibited).
Sentry& operator = (const Sentry &);
private:
Standard_Mutex &myMutex;
Standard_Mutex* myMutex;
};
/**
* @brief Advanced Sentry class providing convenient interface to
* manipulate a mutex from one thread.
*
* As compared with simple Sentry class, provides possibility to
* lock and unlock mutex at any moment, and perform nested lock/unlock
* actions (using lock counter). However all calls must be from within
* the same thread; this is to be ensured by the code using this class.
*/
class SentryNested
{
public:
//! Constructor - initializes the sentry object by reference to a
//! mutex (which must be initialized). Locks the mutex immediately
//! unless Standard_False is given as second argument.
SentryNested (Standard_Mutex &theMutex, Standard_Boolean doLock = Standard_True)
: myMutex(theMutex), nbLocked(0)
{
if ( doLock ) Lock();
}
//! Destructor - unlocks the mutex if already locked.
~SentryNested ()
{
if ( nbLocked >0 ) {
nbLocked = 1;
Unlock();
}
}
//! Lock the mutex
void Lock () {
if ( ! nbLocked ) {
myMutex.Lock();
myMutex.RegisterCallback();
}
nbLocked++;
}
//! Unlock the mutex
void Unlock () {
if ( nbLocked == 1 ) {
myMutex.UnregisterCallback();
myMutex.Unlock();
}
nbLocked--;
}
private:
//! This method should not be called (prohibited).
SentryNested (const SentryNested &);
//! This method should not be called (prohibited).
SentryNested& operator = (const SentryNested &);
private:
Standard_Mutex &myMutex;
Standard_Boolean nbLocked; //!< Note that we do not protect this field from
//!< concurrent access, as it should always be accessed
//!< from within one thread, i.e. synchronously
};
public:
//! Constructor: creates a mutex object and initializes it.
@ -204,7 +168,7 @@ private:
Standard_Mutex& operator = (const Standard_Mutex &);
private:
#ifdef WNT
#if (defined(_WIN32) || defined(__WIN32__))
CRITICAL_SECTION myMutex;
#else
pthread_mutex_t myMutex;
@ -215,10 +179,10 @@ private:
// just a shortcut to system function
inline void Standard_Mutex::Unlock ()
{
#ifdef WNT
LeaveCriticalSection( &myMutex );
#if (defined(_WIN32) || defined(__WIN32__))
LeaveCriticalSection (&myMutex);
#else
pthread_mutex_unlock( &myMutex );
pthread_mutex_unlock (&myMutex);
#endif
}