EgtGeomKernel 2.5f5 :
- aggiunta gestione lock tra thread diversi delle operazioni di lettura, scrittura, copia e relocate nel DB geometrico tramite classe LockAddErase che usa std::atomic_flag.
This commit is contained in:
+70
-9
@@ -30,9 +30,31 @@
|
||||
#include "/EgtDev/Include/SELkKeyProc.h"
|
||||
#include <new>
|
||||
#include <stack>
|
||||
#include <thread>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class LockAddErase
|
||||
{
|
||||
public :
|
||||
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
{ if ( ! m_bUse) return ;
|
||||
while ( m_bAddEraseOn.test_and_set()) {
|
||||
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
~LockAddErase( void)
|
||||
{ if ( ! m_bUse) return ;
|
||||
m_bAddEraseOn.clear() ;
|
||||
} ;
|
||||
|
||||
private :
|
||||
std::atomic_flag& m_bAddEraseOn ;
|
||||
bool m_bUse ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IGeomDB*
|
||||
CreateGeomDB( void)
|
||||
@@ -68,6 +90,7 @@ CreateGeomDB( void)
|
||||
//----------------------------------------------------------------------------
|
||||
GeomDB::GeomDB( void)
|
||||
{
|
||||
m_bAddEraseOn.clear() ;
|
||||
m_GrpRadix.SetGeomDB( this) ;
|
||||
m_GrpRadix.m_nId = GDB_ID_ROOT ;
|
||||
m_GrpRadix.SetMaterial( Color()) ;
|
||||
@@ -595,25 +618,32 @@ GeomDB::GetGdbObj( int nId) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bTestId)
|
||||
GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase, bool bTestId)
|
||||
{
|
||||
// verifico validità oggetto puntato
|
||||
if ( pGObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// se richiesta, verifica validità e unicità del nome
|
||||
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// oggetto e riferimento non possono essere la stessa cosa
|
||||
if ( pGObj->m_nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione, se necessaria
|
||||
LockAddErase Lock( m_bAddEraseOn, bLockAddErase) ;
|
||||
|
||||
// cerco il riferimento
|
||||
GdbObj* pGRef = GetGdbObj( nRefId) ;
|
||||
if ( pGRef == nullptr)
|
||||
return false ;
|
||||
|
||||
// se richiesta, verifica validità e unicità del nome
|
||||
if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)))
|
||||
return false ;
|
||||
|
||||
// assegno il riferimento al DB geometrico
|
||||
pGObj->SetGeomDB( this) ;
|
||||
|
||||
@@ -667,6 +697,8 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// verifico validità apparente RefId
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return GDB_ID_NULL ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità Id
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -681,7 +713,7 @@ GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& fr
|
||||
// assegno riferimento
|
||||
pGdbGroup->SetFrame( frFrame) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGroup ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -702,6 +734,8 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
{
|
||||
// assegno GeoObj a gestore puntatore con rilascio automatico
|
||||
PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico validità identificativo
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
nId = m_IdManager.GetNewId() ;
|
||||
@@ -719,7 +753,7 @@ GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj
|
||||
// assegno dati
|
||||
pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ;
|
||||
// inserisco nel DB
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter)) {
|
||||
if ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter, false)) {
|
||||
delete pGdbGeo ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
@@ -1202,6 +1236,9 @@ GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) con
|
||||
int
|
||||
GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico Id destinazione
|
||||
if ( nIdDest <= GDB_ID_ROOT)
|
||||
nIdDest = m_IdManager.GetNewId() ;
|
||||
@@ -1244,7 +1281,7 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
}
|
||||
|
||||
// inserisco nel DB (non rilascio il puntatore)
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter))
|
||||
if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter, false))
|
||||
return GDB_ID_NULL ;
|
||||
|
||||
// rilascio il puntatore
|
||||
@@ -1256,10 +1293,17 @@ GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGl
|
||||
bool
|
||||
GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
// verifico validità del riferimento
|
||||
if ( nRefId < GDB_ID_ROOT)
|
||||
return false ;
|
||||
|
||||
// l'oggetto e il riferimento non possono coincidere
|
||||
if ( nId == nRefId)
|
||||
return ( ! IS_GDB_SON( nSonBeforeAfter)) ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// verifico esistenza dell'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
if ( pGdbObj == nullptr)
|
||||
@@ -1303,7 +1347,7 @@ GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
pGdbObj->Remove() ;
|
||||
|
||||
// lo inserisco nella posizione opportuna
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false)) {
|
||||
if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false, false)) {
|
||||
// in caso di errore (condizione assai remota qui) cancello tutto
|
||||
m_IdManager.RemoveObj( pGdbObj->m_nId) ;
|
||||
m_SelManager.RemoveObj( pGdbObj) ;
|
||||
@@ -1384,9 +1428,14 @@ GeomDB::GetNewId( void) const
|
||||
bool
|
||||
GeomDB::ChangeId( int nId, int nNewId)
|
||||
{
|
||||
// se Id non validi, ritorno errore
|
||||
if ( nId <= GDB_ID_ROOT || nNewId <= GDB_ID_ROOT)
|
||||
return false ;
|
||||
// se Id identici, non faccio alcunché
|
||||
if ( nNewId == nId)
|
||||
return true ;
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
// verifico nuovo Id
|
||||
if ( ExistsObj( nNewId))
|
||||
return false ;
|
||||
@@ -1427,7 +1476,10 @@ GeomDB::Erase( GdbObj* pGdbObj)
|
||||
if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix)
|
||||
return false ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// notifico eventuale UserObj
|
||||
if ( pGdbObj->m_pUserObj != nullptr) {
|
||||
// recupero il successivo
|
||||
const GdbObj* pGdbNext = pGdbObj->GetNext() ;
|
||||
@@ -1452,6 +1504,10 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
// non si può cancellare il gruppo radice (escludo anche Id non validi)
|
||||
if ( nId <= GDB_ID_ROOT)
|
||||
return nullptr ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// recupero l'oggetto geometrico
|
||||
GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ;
|
||||
if ( pGdbGeo == nullptr)
|
||||
@@ -1459,6 +1515,7 @@ GeomDB::RemoveGeoObjAndErase( int nId)
|
||||
IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ;
|
||||
// annullo il riferimento alla geometria nell'entità
|
||||
pGdbGeo->m_pGeoObj = nullptr ;
|
||||
|
||||
// tolgo dalla lista e disalloco
|
||||
pGdbGeo->Remove() ;
|
||||
delete pGdbGeo ;
|
||||
@@ -1494,6 +1551,10 @@ GeomDB::EmptyGroup( GdbObj* pGdbObj)
|
||||
GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ;
|
||||
if ( pGrp == nullptr)
|
||||
return false ;
|
||||
|
||||
// verifico unicità esecuzione
|
||||
LockAddErase Lock( m_bAddEraseOn) ;
|
||||
|
||||
// lo svuoto
|
||||
return pGrp->Clear() ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user