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
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -22,7 +22,7 @@
|
||||
// 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)
|
||||
#if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
|
||||
@ -35,10 +35,14 @@
|
||||
|
||||
Standard_Mutex::Standard_Mutex ()
|
||||
{
|
||||
#ifdef WNT
|
||||
#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,7 +52,7 @@ Standard_Mutex::Standard_Mutex ()
|
||||
|
||||
Standard_Mutex::~Standard_Mutex ()
|
||||
{
|
||||
#ifdef WNT
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
DeleteCriticalSection (&myMutex);
|
||||
#else
|
||||
pthread_mutex_destroy (&myMutex);
|
||||
@ -61,7 +65,7 @@ Standard_Mutex::~Standard_Mutex ()
|
||||
|
||||
void Standard_Mutex::Lock ()
|
||||
{
|
||||
#ifdef WNT
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
EnterCriticalSection (&myMutex);
|
||||
#else
|
||||
pthread_mutex_lock (&myMutex);
|
||||
@ -74,7 +78,7 @@ void Standard_Mutex::Lock ()
|
||||
|
||||
Standard_Boolean Standard_Mutex::TryLock ()
|
||||
{
|
||||
#ifdef WNT
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
return (TryEnterCriticalSection (&myMutex) != 0);
|
||||
#else
|
||||
return (pthread_mutex_trylock (&myMutex) != EBUSY);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_ErrorHandlerCallback.hxx>
|
||||
|
||||
#ifdef WNT
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
@ -86,89 +86,53 @@ 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
myMutex.Lock();
|
||||
myMutex.RegisterCallback();
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
Standard_Mutex* myMutex;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -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,7 +179,7 @@ private:
|
||||
// just a shortcut to system function
|
||||
inline void Standard_Mutex::Unlock ()
|
||||
{
|
||||
#ifdef WNT
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
LeaveCriticalSection (&myMutex);
|
||||
#else
|
||||
pthread_mutex_unlock (&myMutex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user