From 49cf4baea638787eda4fa57283783eacf72f9c2f Mon Sep 17 00:00:00 2001 From: Pasukhin Dmitry Date: Mon, 10 Nov 2025 21:17:26 +0000 Subject: [PATCH] Coding - Migrate from exception to local status flag for dead loop handling (#817) - Transfer_ProcessForFinder_0.cxx: Replace exception throw/catch with local status flag in Transferring() method - Transfer_ProcessForTransient_0.cxx: Same changes for consistency - Transfer_TransferDeadLoop.hxx: Mark exception class as deprecated with Standard_DEPRECATED attribute The Transfer_TransferDeadLoop class is kept alive but marked as deprecated for backward compatibility. Dead loop detection is now handled via local status flags instead of exceptions, improving performance and code clarity. --- .../Transfer/Transfer_ProcessForFinder_0.cxx | 66 ++++++++----------- .../Transfer_ProcessForTransient_0.cxx | 64 +++++++----------- .../Transfer/Transfer_TransferDeadLoop.hxx | 7 +- 3 files changed, 57 insertions(+), 80 deletions(-) diff --git a/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForFinder_0.cxx b/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForFinder_0.cxx index baf8228ca8..c593d2a17b 100644 --- a/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForFinder_0.cxx +++ b/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForFinder_0.cxx @@ -723,6 +723,7 @@ Handle(Transfer_Binder) Transfer_ProcessForFinder::Transferring( // We consider that this new Transfer request therefore corresponds to a // additional use: note "AlreadyUsed", therefore non-modifiable result + Standard_Boolean hasDeadLoop = Standard_False; if (!former.IsNull()) { if (former->HasResult()) @@ -760,9 +761,11 @@ Handle(Transfer_Binder) Transfer_ProcessForFinder::Transferring( } else StartTrace(former, start, thelevel, 4); - throw Transfer_TransferDeadLoop("TransferProcess : Transfer at Head of a Dead Loop"); + hasDeadLoop = Standard_True; + break; } - former->SetStatusExec(Transfer_StatusRun); + if (!hasDeadLoop) + former->SetStatusExec(Transfer_StatusRun); } #ifdef TRANSLOG std::cout << " GO .." << std::endl; @@ -770,53 +773,36 @@ Handle(Transfer_Binder) Transfer_ProcessForFinder::Transferring( Handle(Transfer_Binder) binder; Standard_Boolean newbind = Standard_False; - if (theerrh) + + // Handle dead loop condition detected before calling TransferProduct + // When hasDeadLoop is true, we know: + // 1. former is NOT null (hasDeadLoop only set inside !former.IsNull() block) + // 2. former->StatusExec() == Transfer_StatusLoop (that's what triggered hasDeadLoop) + if (hasDeadLoop) + { + Message_Messenger::StreamBuffer aSender = themessenger->SendInfo(); + if (thetrace) + { + aSender << " *** Dead Loop : Finding head of Loop :" << std::endl; + StartTrace(former, start, thelevel - 1, 0); + } + else + StartTrace(former, start, thelevel - 1, 4); + binder = former; + binder->AddFail("Transfer: Head of Dead Loop"); + binder->AddFail("Transfer in dead Loop"); + } + else if (theerrh) { Message_Messenger::StreamBuffer aSender = themessenger->SendInfo(); - // Transfer under protection for exceptions (for notification in fact + // Transfer under protection for exceptions (for notification in fact) Standard_Integer oldlev = thelevel; try { OCC_CATCH_SIGNALS binder = TransferProduct(start, theProgress); } - - // Exceptions to catch up on: they are not all the same - catch (Transfer_TransferDeadLoop const&) - { - if (binder.IsNull()) - { - aSender << " *** Dead Loop with no Result" << std::endl; - if (thetrace) - StartTrace(binder, start, thelevel - 1, 0); - binder = new Transfer_VoidBinder; - Bind(start, binder); - newbind = Standard_True; - } - else if (binder->StatusExec() == Transfer_StatusLoop) - { - if (thetrace) - { - aSender << " *** Dead Loop : Finding head of Loop :" << std::endl; - StartTrace(binder, start, thelevel - 1, 0); - } - else - StartTrace(binder, start, thelevel - 1, 4); - throw Transfer_TransferFailure("TransferProcess : Head of Dead Loop"); - // In other words, we change the exception (we exit the loop) - } - else - { - if (thetrace) - { - aSender << " *** Dead Loop : Actor in Loop :" << std::endl; - StartTrace(binder, start, thelevel - 1, 0); - } - } - binder->AddFail("Transfer in dead Loop"); - thelevel = oldlev; - } catch (Standard_Failure const& anException) { if (binder.IsNull()) diff --git a/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForTransient_0.cxx b/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForTransient_0.cxx index 1597665aea..1001b2253f 100644 --- a/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForTransient_0.cxx +++ b/src/DataExchange/TKXSBase/Transfer/Transfer_ProcessForTransient_0.cxx @@ -731,6 +731,7 @@ Handle(Transfer_Binder) Transfer_ProcessForTransient::Transferring( Handle(Transfer_Binder) former = FindAndMask(start); // We consider that this new Transfer request therefore corresponds to a // additional use: note "AlreadyUsed", therefore non-modifiable result + Standard_Boolean hasDeadLoop = Standard_False; if (!former.IsNull()) { if (former->HasResult()) @@ -768,14 +769,35 @@ Handle(Transfer_Binder) Transfer_ProcessForTransient::Transferring( } else StartTrace(former, start, thelevel, 4); - throw Transfer_TransferDeadLoop("TransferProcess : Transfer at Head of a Dead Loop"); + hasDeadLoop = Standard_True; + break; } - former->SetStatusExec(Transfer_StatusRun); + if (!hasDeadLoop) + former->SetStatusExec(Transfer_StatusRun); } Handle(Transfer_Binder) binder; Standard_Boolean newbind = Standard_False; - if (theerrh) + + // Handle dead loop condition detected before calling TransferProduct + // When hasDeadLoop is true, we know: + // 1. former is NOT null (hasDeadLoop only set inside !former.IsNull() block) + // 2. former->StatusExec() == Transfer_StatusLoop (that's what triggered hasDeadLoop) + if (hasDeadLoop) + { + Message_Messenger::StreamBuffer aSender = themessenger->SendInfo(); + if (thetrace) + { + aSender << " *** Dead Loop : Finding head of Loop :" << std::endl; + StartTrace(former, start, thelevel - 1, 0); + } + else + StartTrace(former, start, thelevel - 1, 4); + binder = former; + binder->AddFail("Transfer: Head of Dead Loop"); + binder->AddFail("Transfer in dead Loop"); + } + else if (theerrh) { Message_Messenger::StreamBuffer aSender = themessenger->SendInfo(); @@ -786,42 +808,6 @@ Handle(Transfer_Binder) Transfer_ProcessForTransient::Transferring( OCC_CATCH_SIGNALS binder = TransferProduct(start, theProgress); } - - // Exceptions to catch up on: they are not all the same - catch (Transfer_TransferDeadLoop const&) - { - if (binder.IsNull()) - { - aSender << " *** Dead Loop with no Result" << std::endl; - if (thetrace) - StartTrace(binder, start, thelevel - 1, 0); - binder = new Transfer_VoidBinder; - Bind(start, binder); - newbind = Standard_True; - } - else if (binder->StatusExec() == Transfer_StatusLoop) - { - if (thetrace) - { - aSender << " *** Dead Loop : Finding head of Loop :" << std::endl; - StartTrace(binder, start, thelevel - 1, 0); - } - else - StartTrace(binder, start, thelevel - 1, 4); - throw Transfer_TransferFailure("TransferProcess : Head of Dead Loop"); - // In other words, we change the exception (we exit the loop) - } - else - { - if (thetrace) - { - aSender << " *** Dead Loop : Actor in Loop :" << std::endl; - StartTrace(binder, start, thelevel - 1, 0); - } - } - binder->AddFail("Transfer in dead Loop"); - thelevel = oldlev; - } catch (Standard_Failure const& anException) { if (binder.IsNull()) diff --git a/src/DataExchange/TKXSBase/Transfer/Transfer_TransferDeadLoop.hxx b/src/DataExchange/TKXSBase/Transfer/Transfer_TransferDeadLoop.hxx index 84d8c37cf6..339c9733cc 100644 --- a/src/DataExchange/TKXSBase/Transfer/Transfer_TransferDeadLoop.hxx +++ b/src/DataExchange/TKXSBase/Transfer/Transfer_TransferDeadLoop.hxx @@ -21,10 +21,15 @@ #include #include -class Transfer_TransferDeadLoop; +//! @deprecated OCCT 7.9.0 - This exception is deprecated and no longer thrown. +//! Dead loop detection is now handled via local status flags instead of exceptions. +class Standard_DEPRECATED( + "This exception is no longer thrown; dead loop handling uses local status flags") + Transfer_TransferDeadLoop; DEFINE_STANDARD_HANDLE(Transfer_TransferDeadLoop, Transfer_TransferFailure) #if !defined No_Exception && !defined No_Transfer_TransferDeadLoop + //! @deprecated OCCT 7.9.0 - This macro is deprecated and does nothing. #define Transfer_TransferDeadLoop_Raise_if(CONDITION, MESSAGE) \ if (CONDITION) \ throw Transfer_TransferDeadLoop(MESSAGE); -- 2.39.5