Skip to content

Foundation Classes, Standard_ErrorHandler - use thread_local stack instead of global mutex lock - #980

Merged
dpasukhi merged 1 commit into
Open-Cascade-SAS:IRfrom
dpasukhi:exception_raise
Jan 5, 2026
Merged

dpasukhi merged 1 commit into
Open-Cascade-SAS:IRfrom
dpasukhi:exception_raise

Conversation

@dpasukhi

@dpasukhi dpasukhi commented Jan 5, 2026

Copy link
Copy Markdown
Member

Refactored Standard_ErrorHandler to use thread_local storage for the error handler stack instead of a global list protected by mutex. This eliminates locking overhead entirely since each thread only accesses its own error handlers.

Changes:

  • Replaced global mutex-protected stack with thread_local Top pointer
  • Simplified FindHandler() to directly return the thread-local Top
  • Removed Catches() and LastCaughtError() methods (no longer needed)
  • Added Raise() method for re-throwing caught exceptions
  • Removed obsolete member variables: myStatus, myThread
  • Deleted unused headers: Standard_HandlerStatus.hxx, Standard_JmpBuf.hxx, Standard_PErrorHandler.hxx
  • Updated OCC_CATCH_SIGNALS macro to use new Raise() method

@dpasukhi dpasukhi added this to the Release 8.0 milestone Jan 5, 2026
@dpasukhi
dpasukhi requested a review from Copilot January 5, 2026 10:19
@dpasukhi dpasukhi self-assigned this Jan 5, 2026
@dpasukhi dpasukhi added the 1. Foundation Classes Containers, system calls wrappers, smart pointers and other low level of OCCT code label Jan 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request refactors the error handling mechanism in OCCT's Standard_ErrorHandler class to improve performance in multi-threaded environments. The primary change replaces a global mutex-protected error handler stack with thread-local storage, eliminating synchronization overhead since each thread now only accesses its own error handlers.

Key Changes

  • Converted the global error handler stack from a mutex-protected list to a thread_local pointer, removing all locking overhead
  • Simplified the FindHandler() method to directly return the thread-local top handler
  • Removed obsolete code including unused methods (Catches(), LastCaughtError()), member variables (myStatus, myThread), and header files

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Standard_PErrorHandler.hxx Deleted obsolete typedef header file
Standard_JmpBuf.hxx Deleted obsolete jump buffer typedef header file
Standard_HandlerStatus.hxx Deleted obsolete handler status enum header file
Standard_Failure.cxx Removed redundant Error() call before Abort() in Jump() method
Standard_ErrorHandler.hxx Updated class interface to remove mutex includes, simplify members, and add Raise() method
Standard_ErrorHandler.cxx Refactored implementation to use thread-local storage and simplified handler lookup logic
FILES.cmake Removed deleted header files from build configuration

else
{
return false;
std::cerr << "*** Abort *** an exception handler was called, but not exception object is set."

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected 'not exception object' to 'no exception object' for grammatical correctness.

Suggested change
std::cerr << "*** Abort *** an exception handler was called, but not exception object is set."
std::cerr << "*** Abort *** an exception handler was called, but no exception object is set."

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +48
Standard_ASSERT(Top == this,
"Destroying error handler that is not on top",
while (Top && Top != this) Top->Unlink());

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recovery action in the assertion (unlinking handlers until reaching this) could lead to undefined behavior if the handler is not in the stack at all. The loop doesn't update Top correctly and may cause infinite iteration. Consider adding a safety check to break the loop if we traverse the entire stack without finding this.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +54
if (Top == this)
Top = myPrevious;
else
{
aPrevious->myPrevious = aCurrent->myPrevious;
}
Standard_ASSERT_INVOKE(
"Broken logic of error handlers, likely error handler created not on stack");

Copilot AI Jan 5, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if-else statement without braces violates common C++ style guidelines, particularly for multi-line else blocks. Add braces around both branches for clarity and consistency.

Copilot uses AI. Check for mistakes.
dpasukhi pushed a commit to dpasukhi/OCCT that referenced this pull request Jan 5, 2026
…stead of global mutex lock (Open-Cascade-SAS#980)

Refactored Standard_ErrorHandler to use thread_local storage for the error handler stack
instead of a global list protected by mutex. This eliminates locking overhead entirely
since each thread only accesses its own error handlers.

Changes:
- Replaced global mutex-protected stack with thread_local Top pointer
- Simplified FindHandler() to directly return the thread-local Top
- Removed Catches() and LastCaughtError() methods (no longer needed)
- Added Raise() method for re-throwing caught exceptions
- Removed obsolete member variables: myStatus, myThread
- Deleted unused headers: Standard_HandlerStatus.hxx, Standard_JmpBuf.hxx, Standard_PErrorHandler.hxx
- Updated OCC_CATCH_SIGNALS macro to use new Raise() method
dpasukhi pushed a commit to dpasukhi/OCCT that referenced this pull request Jan 5, 2026
…stead of global mutex lock (Open-Cascade-SAS#980)

Refactored Standard_ErrorHandler to use thread_local storage for the error handler stack
instead of a global list protected by mutex. This eliminates locking overhead entirely
since each thread only accesses its own error handlers.

Changes:
- Replaced global mutex-protected stack with thread_local Top pointer
- Simplified FindHandler() to directly return the thread-local Top
- Removed Catches() and LastCaughtError() methods (no longer needed)
- Added Raise() method for re-throwing caught exceptions
- Removed obsolete member variables: myStatus, myThread
- Deleted unused headers: Standard_HandlerStatus.hxx, Standard_JmpBuf.hxx, Standard_PErrorHandler.hxx
- Updated OCC_CATCH_SIGNALS macro to use new Raise() method
…stead of global mutex lock (Open-Cascade-SAS#980)

Refactored Standard_ErrorHandler to use thread_local storage for the error handler stack
instead of a global list protected by mutex. This eliminates locking overhead entirely
since each thread only accesses its own error handlers.

Changes:
- Replaced global mutex-protected stack with thread_local Top pointer
- Simplified FindHandler() to directly return the thread-local Top
- Removed Catches() and LastCaughtError() methods (no longer needed)
- Added Raise() method for re-throwing caught exceptions
- Removed obsolete member variables: myStatus, myThread
- Deleted unused headers: Standard_HandlerStatus.hxx, Standard_JmpBuf.hxx, Standard_PErrorHandler.hxx
- Updated OCC_CATCH_SIGNALS macro to use new Raise() method
@dpasukhi
dpasukhi merged commit 078dfc4 into Open-Cascade-SAS:IR Jan 5, 2026
18 checks passed
@dpasukhi
dpasukhi deleted the exception_raise branch January 5, 2026 18:36
@github-project-automation github-project-automation Bot moved this from Todo to Done in Maintenance Jan 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1. Foundation Classes Containers, system calls wrappers, smart pointers and other low level of OCCT code

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants