mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
OCC22577 Thread-safety/re-entrability improvements
This commit is contained in:
parent
d30c4db93b
commit
e33e7e78af
@ -3,15 +3,9 @@
|
||||
// Author: Robert COUBLANC
|
||||
// <rob@robox.paris1.matra-dtv.fr>
|
||||
|
||||
|
||||
#include <AIS_GlobalStatus.ixx>
|
||||
#include <TColStd_ListIteratorOfListOfInteger.hxx>
|
||||
|
||||
|
||||
|
||||
static TColStd_ListIteratorOfListOfInteger It;
|
||||
|
||||
|
||||
AIS_GlobalStatus::AIS_GlobalStatus():
|
||||
myStatus(AIS_DS_None),
|
||||
myLayerIndex(0),
|
||||
@ -37,22 +31,32 @@ mySubInt(Standard_False)
|
||||
mySelModes.Append(SMode);
|
||||
}
|
||||
|
||||
|
||||
void AIS_GlobalStatus::RemoveDisplayMode(const Standard_Integer aMode)
|
||||
{
|
||||
for(It.Initialize(myDispModes);It.More();It.Next()){
|
||||
if(It.Value()==aMode){ myDispModes.Remove(It);
|
||||
return;}
|
||||
TColStd_ListIteratorOfListOfInteger anIt (myDispModes);
|
||||
for (; anIt.More(); anIt.Next())
|
||||
{
|
||||
if (anIt.Value() == aMode)
|
||||
{
|
||||
myDispModes.Remove (anIt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AIS_GlobalStatus::RemoveSelectionMode(const Standard_Integer aMode)
|
||||
{
|
||||
for(It.Initialize(mySelModes);It.More();It.Next()){
|
||||
if(It.Value()==aMode){ mySelModes.Remove(It);
|
||||
return;}
|
||||
TColStd_ListIteratorOfListOfInteger anIt (mySelModes);
|
||||
for (; anIt.More(); anIt.Next())
|
||||
{
|
||||
if (anIt.Value() == aMode)
|
||||
{
|
||||
mySelModes.Remove (anIt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AIS_GlobalStatus::ClearSelectionModes()
|
||||
{
|
||||
mySelModes.Clear();
|
||||
@ -60,16 +64,26 @@ void AIS_GlobalStatus::ClearSelectionModes()
|
||||
|
||||
Standard_Boolean AIS_GlobalStatus::IsDModeIn(const Standard_Integer aMode) const
|
||||
{
|
||||
for(It.Initialize(myDispModes);It.More();It.Next())
|
||||
if(It.Value()==aMode) return Standard_True;
|
||||
TColStd_ListIteratorOfListOfInteger anIt (myDispModes);
|
||||
for (; anIt.More(); anIt.Next())
|
||||
{
|
||||
if (anIt.Value() == aMode)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean AIS_GlobalStatus::IsSModeIn(const Standard_Integer aMode) const
|
||||
{
|
||||
for(It.Initialize(mySelModes);It.More();It.Next())
|
||||
if(It.Value()==aMode) return Standard_True;
|
||||
TColStd_ListIteratorOfListOfInteger anIt (mySelModes);
|
||||
for (; anIt.More(); anIt.Next())
|
||||
{
|
||||
if (anIt.Value() == aMode)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include <Prs3d_DatumAspect.hxx>
|
||||
#include <Prs3d_PlaneAspect.hxx>
|
||||
#include <PrsMgr_PresentableObject.hxx>
|
||||
#include <Standard_Atomic.hxx>
|
||||
#include <UnitsAPI.hxx>
|
||||
|
||||
#include <AIS_Trihedron.hxx>
|
||||
@ -91,28 +92,23 @@ static Standard_Boolean AISDebugModeOn()
|
||||
return (isDebugMode != 0);
|
||||
}
|
||||
|
||||
static TCollection_AsciiString AIS_Context_NewSelName()
|
||||
namespace
|
||||
{
|
||||
static Standard_Integer index_sel = 1;
|
||||
TCollection_AsciiString name("AIS_SelContext_");
|
||||
TCollection_AsciiString theind(index_sel);
|
||||
name += theind;
|
||||
index_sel++;
|
||||
return name;
|
||||
}
|
||||
static volatile Standard_Integer THE_AIS_INDEX_SEL = 0;
|
||||
static volatile Standard_Integer THE_AIS_INDEX_CUR = 0;
|
||||
|
||||
static TCollection_AsciiString AIS_Context_NewCurName()
|
||||
{
|
||||
static Standard_Integer index_cur = 1;
|
||||
TCollection_AsciiString name("AIS_CurContext_");
|
||||
TCollection_AsciiString theind(index_cur);
|
||||
name += theind;
|
||||
index_cur++;
|
||||
return name;
|
||||
}
|
||||
|
||||
static TColStd_ListIteratorOfListOfInteger ItL;
|
||||
static TCollection_AsciiString AIS_Context_NewSelName()
|
||||
{
|
||||
return TCollection_AsciiString ("AIS_SelContext_")
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_AIS_INDEX_SEL));
|
||||
}
|
||||
|
||||
static TCollection_AsciiString AIS_Context_NewCurName()
|
||||
{
|
||||
return TCollection_AsciiString ("AIS_CurContext_")
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_AIS_INDEX_CUR));
|
||||
}
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : AIS_InteractiveContext
|
||||
@ -504,7 +500,8 @@ void AIS_InteractiveContext::Display(const Handle(AIS_InteractiveObject)& anIObj
|
||||
updcol = updateviewer;
|
||||
}// attention on fait expres de ne pas mettre de break..
|
||||
case AIS_DS_FullErased:{
|
||||
for (ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes());
|
||||
for (;ItL.More();ItL.Next()){
|
||||
myMainPM->Display(anIObj,ItL.Value());
|
||||
if(STATUS->IsSubIntensityOn())
|
||||
myMainPM->Color(anIObj,mySubIntensity,ItL.Value());
|
||||
@ -523,7 +520,8 @@ void AIS_InteractiveContext::Display(const Handle(AIS_InteractiveObject)& anIObj
|
||||
// Finally, activate selection mode <SelMode> if not yet activated.
|
||||
case AIS_DS_Displayed:{
|
||||
TColStd_ListOfInteger aModesToRemove;
|
||||
for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes());
|
||||
for(;ItL.More();ItL.Next()){
|
||||
|
||||
Standard_Integer OldMode = ItL.Value();
|
||||
|
||||
@ -1817,7 +1815,8 @@ void AIS_InteractiveContext::SetDisplayMode(const Handle(AIS_InteractiveObject)&
|
||||
// SAN : erase presentations for all display modes different from <aMode>
|
||||
if(STATUS->GraphicStatus()==AIS_DS_Displayed){
|
||||
TColStd_ListOfInteger aModesToRemove;
|
||||
for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes());
|
||||
for(;ItL.More();ItL.Next()){
|
||||
|
||||
Standard_Integer OldMode = ItL.Value();
|
||||
|
||||
@ -2092,7 +2091,7 @@ void AIS_InteractiveContext::SetDeviationAngle(
|
||||
|
||||
if(!anIObj->HasInteractiveContext())
|
||||
anIObj->SetContext(this);
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
if(anIObj->Type()!=AIS_KOI_Shape) return;
|
||||
if(anIObj->Signature()!=0) return;
|
||||
(*((Handle(AIS_Shape)*)&anIObj))->SetOwnDeviationAngle(anAngle);
|
||||
@ -2134,7 +2133,7 @@ void AIS_InteractiveContext::SetAngleAndDeviation(
|
||||
if(!anIObj->HasInteractiveContext())
|
||||
anIObj->SetContext(this);
|
||||
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
if(anIObj->Type()!=AIS_KOI_Shape) return;
|
||||
if(anIObj->Signature()!=0) return;
|
||||
(*((Handle(AIS_Shape)*)&anIObj))->SetAngleAndDeviation(anAngle);
|
||||
@ -2162,7 +2161,7 @@ void AIS_InteractiveContext::SetHLRAngleAndDeviation(
|
||||
if(!anIObj->HasInteractiveContext())
|
||||
anIObj->SetContext(this);
|
||||
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
if(anIObj->Type()!=AIS_KOI_Shape) return;
|
||||
if(anIObj->Signature()!=0) return;
|
||||
(*((Handle(AIS_Shape)*)&anIObj))->SetHLRAngleAndDeviation(anAngle);
|
||||
@ -2205,7 +2204,7 @@ void AIS_InteractiveContext::SetHLRDeviationAngle(
|
||||
|
||||
if(!anIObj->HasInteractiveContext())
|
||||
anIObj->SetContext(this);
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
// To be modified after the related methods of AIS_Shape are passed to InteractiveObject
|
||||
if( anIObj->Type()!=AIS_KOI_Shape) return;
|
||||
if(anIObj->Signature()!=0) return;
|
||||
(*((Handle(AIS_Shape)*)&anIObj))->SetOwnHLRDeviationAngle(anAngle);
|
||||
@ -2626,7 +2625,8 @@ void AIS_InteractiveContext::Status(const Handle(AIS_InteractiveObject)& anIObj,
|
||||
break;
|
||||
}
|
||||
astatus += "\t| Active Display Modes in the MainViewer :\n";
|
||||
for(ItL.Initialize(ST->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (ST->DisplayedModes());
|
||||
for(;ItL.More();ItL.Next()){
|
||||
astatus += "\t|\t Mode ";
|
||||
astatus += TCollection_AsciiString(ItL.Value());
|
||||
astatus+="\n";
|
||||
@ -2688,7 +2688,8 @@ void AIS_InteractiveContext::EraseGlobal(const Handle(AIS_InteractiveObject)& an
|
||||
Standard_Integer Dmode = anIObj->HasHilightMode() ? anIObj->HilightMode() : 0;
|
||||
if(STATUS->GraphicStatus()==AIS_DS_Displayed){
|
||||
|
||||
for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes());
|
||||
for(;ItL.More();ItL.Next()){
|
||||
if(myMainPM->IsHighlighted(anIObj,ItL.Value()))
|
||||
myMainPM->Unhighlight(anIObj,ItL.Value());
|
||||
myMainPM->Erase(anIObj,ItL.Value());
|
||||
@ -2732,7 +2733,8 @@ void AIS_InteractiveContext::ClearGlobal(const Handle(AIS_InteractiveObject)& an
|
||||
// const Handle(AIS_GlobalStatus)& STATUS = myObjects(anIObj);
|
||||
Handle(AIS_GlobalStatus) STATUS = myObjects(anIObj);
|
||||
// ENDCLE
|
||||
for(ItL.Initialize(STATUS->DisplayedModes());ItL.More();ItL.Next()){
|
||||
TColStd_ListIteratorOfListOfInteger ItL (STATUS->DisplayedModes());
|
||||
for(;ItL.More();ItL.Next()){
|
||||
if(STATUS->IsHilighted()){
|
||||
if(IsCurrent(anIObj))
|
||||
#ifdef OCC204
|
||||
|
@ -23,12 +23,9 @@ void Handle(Standard_Transient)::Assign (const Standard_Transient *anItem)
|
||||
|
||||
void Handle(Standard_Transient)::BeginScope()
|
||||
{
|
||||
if (entity != UndefinedHandleAddress)
|
||||
if (entity != UndefinedHandleAddress)
|
||||
{
|
||||
if ( Standard::IsReentrant() )
|
||||
Standard_Atomic_Increment (&entity->count);
|
||||
else
|
||||
entity->count++;
|
||||
Standard_Atomic_Increment (&entity->count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,11 +33,9 @@ void Handle(Standard_Transient)::BeginScope()
|
||||
|
||||
void Handle(Standard_Transient)::EndScope()
|
||||
{
|
||||
if (entity == UndefinedHandleAddress)
|
||||
if (entity == UndefinedHandleAddress)
|
||||
return;
|
||||
if ( Standard::IsReentrant() ?
|
||||
Standard_Atomic_DecrementTest (&entity->count) :
|
||||
(--entity->count == 0) )
|
||||
if (Standard_Atomic_Decrement (&entity->count) == 0)
|
||||
entity->Delete();
|
||||
entity = UndefinedHandleAddress;
|
||||
}
|
||||
|
@ -10,91 +10,95 @@
|
||||
//! By the moment, only operations necessary for reference counter
|
||||
//! in Standard_Transient objects are implemented.
|
||||
//!
|
||||
//! Currently only two x86-based configurations (Windows NT with
|
||||
//! MS VC++ compiler and Linix with GCC) are really supported.
|
||||
//! Other configurations use non-atomic C equivalent.
|
||||
//! This is preffered to use fixed size types "int32_t" / "int64_t" for
|
||||
//! correct function declarations however we leave "int" assuming it is 32bits for now.
|
||||
|
||||
//! @fn void Standard_Atomic_Increment (int volatile* var)
|
||||
//! @brief Increments atomically integer variable pointed by var
|
||||
#ifndef _Standard_Atomic_HeaderFile
|
||||
#define _Standard_Atomic_HeaderFile
|
||||
|
||||
//! @fn int Standard_Atomic_DecrementTest (int volatile* var)
|
||||
//! @brief Decrements atomically integer variable pointed by var;
|
||||
//! returns 1 if result is zero, 0 otherwise
|
||||
|
||||
//===================================================
|
||||
// Windows NT, MSVC++ compiler
|
||||
//===================================================
|
||||
#if defined(WNT)
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#if (defined(_WIN32) || defined(__WIN32__))
|
||||
extern "C" {
|
||||
long _InterlockedIncrement(long volatile* lpAddend);
|
||||
long _InterlockedDecrement(long volatile* lpAddend);
|
||||
long _InterlockedIncrement(long volatile* lpAddend);
|
||||
long _InterlockedDecrement(long volatile* lpAddend);
|
||||
}
|
||||
|
||||
#pragma intrinsic (_InterlockedIncrement)
|
||||
#pragma intrinsic (_InterlockedDecrement)
|
||||
|
||||
inline void Standard_Atomic_Increment (int volatile* var)
|
||||
{
|
||||
_InterlockedIncrement (reinterpret_cast<long volatile*>(var));
|
||||
}
|
||||
|
||||
inline int Standard_Atomic_DecrementTest (int volatile* var)
|
||||
{
|
||||
return _InterlockedDecrement (reinterpret_cast<long volatile*>(var)) == 0;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Linux, GCC compiler
|
||||
// Note: Linux kernel 2.6x provides definitions for atomic operators
|
||||
// in the header file /usr/include/asm/atomic.h,
|
||||
// however these definitions involve specific type atomic_t
|
||||
// Note: The same code probably would work for Intel compiler
|
||||
//===================================================
|
||||
#elif defined(LIN)
|
||||
|
||||
inline void Standard_Atomic_Increment (int volatile* var)
|
||||
{
|
||||
// C equivalent:
|
||||
// ++(*var);
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock incl %0"
|
||||
: "=m"(*var) // out
|
||||
: "m" (*var) // in
|
||||
);
|
||||
}
|
||||
|
||||
inline int Standard_Atomic_DecrementTest (int volatile* var)
|
||||
{
|
||||
// C equivalent:
|
||||
// return --(*var) == 0;
|
||||
|
||||
unsigned char c;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"lock decl %0; sete %1"
|
||||
: "=m"(*var), "=qm"(c) // out
|
||||
: "m" (*var) // in
|
||||
: "memory"
|
||||
);
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
// Default stub implementation, not atomic actually
|
||||
//===================================================
|
||||
#else
|
||||
|
||||
inline void Standard_Atomic_Increment (int volatile* var)
|
||||
{
|
||||
++(*var);
|
||||
}
|
||||
|
||||
inline int Standard_Atomic_DecrementTest (int volatile* var)
|
||||
{
|
||||
return --(*var) == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// force intrinsic instead of WinAPI calls
|
||||
#pragma intrinsic (_InterlockedIncrement)
|
||||
#pragma intrinsic (_InterlockedDecrement)
|
||||
#endif
|
||||
|
||||
//! Increments atomically integer variable pointed by theValue
|
||||
//! and returns resulting incremented value.
|
||||
static int Standard_Atomic_Increment (volatile int* theValue)
|
||||
{
|
||||
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
|
||||
// mordern g++ compiler (gcc4.4+)
|
||||
// built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform)
|
||||
return __sync_add_and_fetch (theValue, 1);
|
||||
#elif (defined(_WIN32) || defined(__WIN32__))
|
||||
// WinAPI function or MSVC intrinsic
|
||||
return _InterlockedIncrement(reinterpret_cast<long volatile*>(theValue));
|
||||
#elif defined(LIN)
|
||||
// use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC)
|
||||
int anIncResult;
|
||||
__asm__ __volatile__ (
|
||||
#if defined(_OCC64)
|
||||
"lock xaddl %%ebx, (%%rax) \n\t"
|
||||
"incl %%ebx \n\t"
|
||||
: "=b" (anIncResult)
|
||||
: "a" (theValue), "b" (1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\t"
|
||||
"incl %%eax \n\t"
|
||||
: "=a" (anIncResult)
|
||||
: "c" (theValue), "a" (1)
|
||||
: "memory");
|
||||
#endif
|
||||
return anIncResult;
|
||||
#else
|
||||
//#error "Atomic operation doesn't implemented for current platform!"
|
||||
return ++(*theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Decrements atomically integer variable pointed by theValue
|
||||
//! and returns resulting decremented value.
|
||||
static int Standard_Atomic_Decrement (volatile int* theValue)
|
||||
{
|
||||
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
|
||||
// mordern g++ compiler (gcc4.4+)
|
||||
// built-in functions available for appropriate CPUs (at least -march=i486 should be specified on x86 platform)
|
||||
return __sync_sub_and_fetch (theValue, 1);
|
||||
#elif (defined(_WIN32) || defined(__WIN32__))
|
||||
// WinAPI function or MSVC intrinsic
|
||||
return _InterlockedDecrement(reinterpret_cast<long volatile*>(theValue));
|
||||
#elif defined(LIN)
|
||||
// use x86 / x86_64 inline assembly (compatibility with alien compilers / old GCC)
|
||||
int aDecResult;
|
||||
__asm__ __volatile__ (
|
||||
#if defined(_OCC64)
|
||||
"lock xaddl %%ebx, (%%rax) \n\t"
|
||||
"decl %%ebx \n\t"
|
||||
: "=b" (aDecResult)
|
||||
: "a" (theValue), "b" (-1)
|
||||
: "cc", "memory");
|
||||
#else
|
||||
"lock xaddl %%eax, (%%ecx) \n\t"
|
||||
"decl %%eax \n\t"
|
||||
: "=a" (aDecResult)
|
||||
: "c" (theValue), "a" (-1)
|
||||
: "memory");
|
||||
#endif
|
||||
return aDecResult;
|
||||
#else
|
||||
//#error "Atomic operation doesn't implemented for current platform!"
|
||||
return --(*theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //_Standard_Atomic_HeaderFile
|
||||
|
@ -86,7 +86,7 @@ class Standard_Transient
|
||||
|
||||
private:
|
||||
|
||||
Standard_Integer count;
|
||||
volatile Standard_Integer count;
|
||||
};
|
||||
|
||||
Standard_EXPORT const Handle(Standard_Type)& STANDARD_TYPE(Standard_Transient);
|
||||
|
Loading…
x
Reference in New Issue
Block a user