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:
parent
581971fef3
commit
49f38e37fc
@ -57,8 +57,6 @@
|
|||||||
|
|
||||||
#define UVDEFLECTION 1.e-05
|
#define UVDEFLECTION 1.e-05
|
||||||
|
|
||||||
static Standard_Mutex DummyMutex;
|
|
||||||
|
|
||||||
static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
|
static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
|
||||||
{
|
{
|
||||||
Standard_Integer i, j, n = 0;
|
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
|
// lock mutex during querying data from edge curves to prevent parallel change of the same data
|
||||||
Standard_Mutex* aMutex = theMutexProvider.GetMutex(theEdge);
|
Standard_Mutex* aMutex = theMutexProvider.GetMutex(theEdge);
|
||||||
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
|
Standard_Mutex::Sentry aSentry (aMutex);
|
||||||
aMutex != NULL);
|
|
||||||
|
|
||||||
Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
|
Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
|
||||||
if (Poly.IsNull() || !Poly->HasParameters())
|
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
|
// lock mutex to prevent parallel change of the same data
|
||||||
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
|
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
|
||||||
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
|
Standard_Mutex::Sentry aSentry (aMutex);
|
||||||
aMutex != NULL);
|
|
||||||
|
|
||||||
if ( NOD1 == NOD2 ) {
|
if ( NOD1 == NOD2 ) {
|
||||||
B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc);
|
B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc);
|
||||||
|
@ -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;
|
// 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
|
// note that this is done by sentry class so as to ensure unlocking in case of
|
||||||
// possible exception that may be thrown from AllocMemory()
|
// 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
|
// check for availability of requested space in the current pool
|
||||||
Standard_Size *aBlock = myNextAddr;
|
Standard_Size *aBlock = myNextAddr;
|
||||||
@ -533,7 +533,7 @@ void Standard_MMgrOpt::Free(Standard_Address& theStorage)
|
|||||||
Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean )//isDeleted)
|
Standard_Integer Standard_MMgrOpt::Purge(Standard_Boolean )//isDeleted)
|
||||||
{
|
{
|
||||||
// Lock access to critical data by mutex
|
// 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
|
// 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
|
// 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;
|
// release memory pools containing no busy memory;
|
||||||
// for that for each pool count the summary size of blocks
|
// 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()
|
void Standard_MMgrOpt::FreePools()
|
||||||
{
|
{
|
||||||
// Lock access to critical data by mutex
|
// 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
|
// last pool is remembered in myAllocList
|
||||||
Standard_Size * aFree = myAllocList;
|
Standard_Size * aFree = myAllocList;
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
// and is surrounded by #ifdef in MS VC++ 7.1 headers.
|
// 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
|
// Thus to use it we need to define appropriate macro saying that we wil
|
||||||
// run on Windows NT 4.0 at least
|
// run on Windows NT 4.0 at least
|
||||||
#if defined(WNT) && ! defined(_WIN32_WINNT)
|
#if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
|
||||||
#define _WIN32_WINNT 0x0400
|
#define _WIN32_WINNT 0x0400
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Standard_Mutex.hxx>
|
#include <Standard_Mutex.hxx>
|
||||||
@ -35,10 +35,14 @@
|
|||||||
|
|
||||||
Standard_Mutex::Standard_Mutex ()
|
Standard_Mutex::Standard_Mutex ()
|
||||||
{
|
{
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
InitializeCriticalSection( &myMutex );
|
InitializeCriticalSection (&myMutex);
|
||||||
#else
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +52,10 @@ Standard_Mutex::Standard_Mutex ()
|
|||||||
|
|
||||||
Standard_Mutex::~Standard_Mutex ()
|
Standard_Mutex::~Standard_Mutex ()
|
||||||
{
|
{
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
DeleteCriticalSection( &myMutex );
|
DeleteCriticalSection (&myMutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_destroy( &myMutex );
|
pthread_mutex_destroy (&myMutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,10 +65,10 @@ Standard_Mutex::~Standard_Mutex ()
|
|||||||
|
|
||||||
void Standard_Mutex::Lock ()
|
void Standard_Mutex::Lock ()
|
||||||
{
|
{
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
EnterCriticalSection( &myMutex );
|
EnterCriticalSection (&myMutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock( &myMutex );
|
pthread_mutex_lock (&myMutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,10 +78,10 @@ void Standard_Mutex::Lock ()
|
|||||||
|
|
||||||
Standard_Boolean Standard_Mutex::TryLock ()
|
Standard_Boolean Standard_Mutex::TryLock ()
|
||||||
{
|
{
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
return ( TryEnterCriticalSection( &myMutex ) != 0 );
|
return (TryEnterCriticalSection (&myMutex) != 0);
|
||||||
#else
|
#else
|
||||||
return ( pthread_mutex_trylock( &myMutex ) != EBUSY );
|
return (pthread_mutex_trylock (&myMutex) != EBUSY);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
#include <Standard_Boolean.hxx>
|
#include <Standard_Boolean.hxx>
|
||||||
#include <Standard_ErrorHandlerCallback.hxx>
|
#include <Standard_ErrorHandlerCallback.hxx>
|
||||||
|
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,92 +85,56 @@ public:
|
|||||||
|
|
||||||
//! Constructor - initializes the sentry object by reference to a
|
//! Constructor - initializes the sentry object by reference to a
|
||||||
//! mutex (which must be initialized) and locks the mutex immediately
|
//! mutex (which must be initialized) and locks the mutex immediately
|
||||||
Sentry (Standard_Mutex &theMutex)
|
Sentry (Standard_Mutex& theMutex)
|
||||||
: myMutex(theMutex)
|
: myMutex (&theMutex)
|
||||||
{
|
{
|
||||||
myMutex.Lock();
|
Lock();
|
||||||
myMutex.RegisterCallback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! 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.
|
//! Destructor - unlocks the mutex if already locked.
|
||||||
~Sentry () {
|
~Sentry()
|
||||||
myMutex.UnregisterCallback();
|
{
|
||||||
myMutex.Unlock();
|
if (myMutex != NULL)
|
||||||
|
{
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
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).
|
//! This method should not be called (prohibited).
|
||||||
Sentry (const Sentry &);
|
Sentry (const Sentry &);
|
||||||
//! This method should not be called (prohibited).
|
//! This method should not be called (prohibited).
|
||||||
Sentry& operator = (const Sentry &);
|
Sentry& operator = (const Sentry &);
|
||||||
|
|
||||||
private:
|
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:
|
public:
|
||||||
|
|
||||||
//! Constructor: creates a mutex object and initializes it.
|
//! Constructor: creates a mutex object and initializes it.
|
||||||
@ -204,7 +168,7 @@ private:
|
|||||||
Standard_Mutex& operator = (const Standard_Mutex &);
|
Standard_Mutex& operator = (const Standard_Mutex &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
CRITICAL_SECTION myMutex;
|
CRITICAL_SECTION myMutex;
|
||||||
#else
|
#else
|
||||||
pthread_mutex_t myMutex;
|
pthread_mutex_t myMutex;
|
||||||
@ -215,10 +179,10 @@ private:
|
|||||||
// just a shortcut to system function
|
// just a shortcut to system function
|
||||||
inline void Standard_Mutex::Unlock ()
|
inline void Standard_Mutex::Unlock ()
|
||||||
{
|
{
|
||||||
#ifdef WNT
|
#if (defined(_WIN32) || defined(__WIN32__))
|
||||||
LeaveCriticalSection( &myMutex );
|
LeaveCriticalSection (&myMutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_unlock( &myMutex );
|
pthread_mutex_unlock (&myMutex);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user