Foundation Classes, Standard_ErrorHandler - use thread_local stack instead of global mutex lock - #980
Conversation
There was a problem hiding this comment.
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_localpointer, 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." |
There was a problem hiding this comment.
Corrected 'not exception object' to 'no exception object' for grammatical correctness.
| 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." |
| Standard_ASSERT(Top == this, | ||
| "Destroying error handler that is not on top", | ||
| while (Top && Top != this) Top->Unlink()); |
There was a problem hiding this comment.
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.
| 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"); |
There was a problem hiding this comment.
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.
2fe062e to
e230b6d
Compare
…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
e230b6d to
b6f3bcf
Compare
…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
b6f3bcf to
9b0c04a
Compare
…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
9b0c04a to
078dfc4
Compare
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: