mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Make the error-handling functions thread-safe.
Prior to this change, error handling functions must be installed and removed only inside of an llvm_[start/stop]_multithreading pair. This change allows error handling functions to be installed any time, and from any thread. Reviewed by: chandlerc Differential Revision: http://reviews.llvm.org/D4140 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210937 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -30,9 +30,6 @@ namespace llvm { | |||||||
|   /// install_fatal_error_handler - Installs a new error handler to be used |   /// install_fatal_error_handler - Installs a new error handler to be used | ||||||
|   /// whenever a serious (non-recoverable) error is encountered by LLVM. |   /// whenever a serious (non-recoverable) error is encountered by LLVM. | ||||||
|   /// |   /// | ||||||
|   /// If you are using llvm_start_multithreaded, you should register the handler |  | ||||||
|   /// before doing that. |  | ||||||
|   /// |  | ||||||
|   /// If no error handler is installed the default is to print the error message |   /// If no error handler is installed the default is to print the error message | ||||||
|   /// to stderr, and call exit(1).  If an error handler is installed then it is |   /// to stderr, and call exit(1).  If an error handler is installed then it is | ||||||
|   /// the handler's responsibility to log the message, it will no longer be |   /// the handler's responsibility to log the message, it will no longer be | ||||||
| @@ -50,8 +47,6 @@ namespace llvm { | |||||||
|                                    void *user_data = nullptr); |                                    void *user_data = nullptr); | ||||||
|  |  | ||||||
|   /// Restores default error handling behaviour. |   /// Restores default error handling behaviour. | ||||||
|   /// This must not be called between llvm_start_multithreaded() and |  | ||||||
|   /// llvm_stop_multithreaded(). |  | ||||||
|   void remove_fatal_error_handler(); |   void remove_fatal_error_handler(); | ||||||
|  |  | ||||||
|   /// ScopedFatalErrorHandler - This is a simple helper class which just |   /// ScopedFatalErrorHandler - This is a simple helper class which just | ||||||
|   | |||||||
| @@ -19,6 +19,8 @@ | |||||||
| #include "llvm/Config/config.h" | #include "llvm/Config/config.h" | ||||||
| #include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | ||||||
| #include "llvm/Support/Signals.h" | #include "llvm/Support/Signals.h" | ||||||
|  | #include "llvm/Support/Mutex.h" | ||||||
|  | #include "llvm/Support/MutexGuard.h" | ||||||
| #include "llvm/Support/Threading.h" | #include "llvm/Support/Threading.h" | ||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
| #include <cassert> | #include <cassert> | ||||||
| @@ -37,17 +39,20 @@ using namespace llvm; | |||||||
| static fatal_error_handler_t ErrorHandler = nullptr; | static fatal_error_handler_t ErrorHandler = nullptr; | ||||||
| static void *ErrorHandlerUserData = nullptr; | static void *ErrorHandlerUserData = nullptr; | ||||||
|  |  | ||||||
|  | static sys::Mutex ErrorHandlerMutex; | ||||||
|  |  | ||||||
| void llvm::install_fatal_error_handler(fatal_error_handler_t handler, | void llvm::install_fatal_error_handler(fatal_error_handler_t handler, | ||||||
|                                        void *user_data) { |                                        void *user_data) { | ||||||
|   assert(!llvm_is_multithreaded() && |   llvm::MutexGuard Lock(ErrorHandlerMutex); | ||||||
|          "Cannot register error handlers after starting multithreaded mode!\n"); |  | ||||||
|   assert(!ErrorHandler && "Error handler already registered!\n"); |   assert(!ErrorHandler && "Error handler already registered!\n"); | ||||||
|   ErrorHandler = handler; |   ErrorHandler = handler; | ||||||
|   ErrorHandlerUserData = user_data; |   ErrorHandlerUserData = user_data; | ||||||
| } | } | ||||||
|  |  | ||||||
| void llvm::remove_fatal_error_handler() { | void llvm::remove_fatal_error_handler() { | ||||||
|  |   llvm::MutexGuard Lock(ErrorHandlerMutex); | ||||||
|   ErrorHandler = nullptr; |   ErrorHandler = nullptr; | ||||||
|  |   ErrorHandlerUserData = nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) { | void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) { | ||||||
| @@ -63,8 +68,18 @@ void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { | void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { | ||||||
|   if (ErrorHandler) { |   llvm::fatal_error_handler_t handler = nullptr; | ||||||
|     ErrorHandler(ErrorHandlerUserData, Reason.str(), GenCrashDiag); |   void* handlerData = nullptr; | ||||||
|  |   { | ||||||
|  |     // Only acquire the mutex while reading the handler, so as not to invoke a | ||||||
|  |     // user-supplied callback under a lock. | ||||||
|  |     llvm::MutexGuard Lock(ErrorHandlerMutex); | ||||||
|  |     handler = ErrorHandler; | ||||||
|  |     handlerData = ErrorHandlerUserData; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (handler) { | ||||||
|  |     handler(handlerData, Reason.str(), GenCrashDiag); | ||||||
|   } else { |   } else { | ||||||
|     // Blast the result out to stderr.  We don't try hard to make sure this |     // Blast the result out to stderr.  We don't try hard to make sure this | ||||||
|     // succeeds (e.g. handling EINTR) and we can't use errs() here because |     // succeeds (e.g. handling EINTR) and we can't use errs() here because | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user