![]() |
|
|||
File indexing completed on 2025-09-18 09:09:43
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file corecel/sys/ScopedSignalHandler.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include <initializer_list> 0010 #include <utility> 0011 #include <vector> 0012 0013 namespace celeritas 0014 { 0015 //---------------------------------------------------------------------------// 0016 /*! 0017 * Catch the given signal type within the scope of the handler. 0018 * 0019 * On instantiation with a non-empty argument, this class registers a signal 0020 * handler for the given signal. A class instance is true if and only if the 0021 * class is handling a signal. The instance's "call" operator will check and 0022 * return whether the assigned signal has been caught. The move-assign operator 0023 * can be used to unregister the handle. 0024 * 0025 * When the class exits scope, the signal for the active type will be cleared. 0026 * 0027 * Signal handling can be disabled by setting the environment variable \c 0028 * CELER_DISABLE_SIGNALS to a 0029 * non-empty value, but hopefully this will not be necessary because signal 0030 * handling should be used sparingly. 0031 * 0032 * \code 0033 #include <csignal> 0034 0035 int main() 0036 { 0037 ScopedSignalHandler interrupted(SIGINT); 0038 0039 while (true) 0040 { 0041 if (interrupted()) 0042 { 0043 CELER_LOG(error) << "Interrupted"; 0044 break; 0045 } 0046 0047 if (stop_handling_for_whatever_reason()) 0048 { 0049 // Clear handler 0050 interrupted = {}; 0051 } 0052 } 0053 return interrupted() ? 1 : 0; 0054 } 0055 \endcode 0056 */ 0057 class ScopedSignalHandler 0058 { 0059 public: 0060 //!@{ 0061 //! \name Type aliases 0062 using signal_type = int; 0063 //!@} 0064 0065 public: 0066 // Whether signals are enabled 0067 static bool allow_signals(); 0068 0069 // Raise a signal visible only to ScopedSignalHandler (for testing) 0070 static int raise(signal_type sig); 0071 0072 //! Default to not handling any signals. 0073 ScopedSignalHandler() = default; 0074 0075 // Handle the given signal type, asserting if it's already been raised 0076 explicit ScopedSignalHandler(signal_type); 0077 0078 // Handle the given signal types 0079 explicit ScopedSignalHandler(std::initializer_list<signal_type>); 0080 0081 // Release the given signal 0082 ~ScopedSignalHandler(); 0083 0084 // Check if signal was intercepted 0085 inline bool operator()() const; 0086 0087 //! True if handling a signal 0088 explicit operator bool() const { return mask_ != 0; } 0089 0090 // Move construct and assign to capture/release signal handling 0091 ScopedSignalHandler(ScopedSignalHandler const&) = delete; 0092 ScopedSignalHandler& operator=(ScopedSignalHandler const&) = delete; 0093 ScopedSignalHandler(ScopedSignalHandler&&) noexcept; 0094 ScopedSignalHandler& operator=(ScopedSignalHandler&&) noexcept; 0095 void swap(ScopedSignalHandler& other) noexcept; 0096 0097 private: 0098 using HandlerPtr = void (*)(int); 0099 using PairSigHandle = std::pair<signal_type, HandlerPtr>; 0100 using VecSH = std::vector<PairSigHandle>; 0101 0102 signal_type mask_{0}; 0103 VecSH handles_; 0104 0105 bool check_signal() const; 0106 }; 0107 0108 //---------------------------------------------------------------------------// 0109 // INLINE DEFINITIONS 0110 //---------------------------------------------------------------------------// 0111 /*! 0112 * Return whether a signal was intercepted. 0113 */ 0114 bool ScopedSignalHandler::operator()() const 0115 { 0116 return *this && this->check_signal(); 0117 } 0118 0119 //---------------------------------------------------------------------------// 0120 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |