signalinterrupt.h raw

   1  // Copyright (c) 2023 The Limenka developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #ifndef LIMENKA_UTIL_SIGNALINTERRUPT_H
   6  #define LIMENKA_UTIL_SIGNALINTERRUPT_H
   7  
   8  #ifdef WIN32
   9  #include <condition_variable>
  10  #include <mutex>
  11  #else
  12  #include <util/tokenpipe.h>
  13  #endif
  14  
  15  #include <atomic>
  16  #include <cstdlib>
  17  
  18  namespace util {
  19  /**
  20   * Helper class that manages an interrupt flag, and allows a thread or
  21   * signal to interrupt another thread.
  22   *
  23   * This class is safe to be used in a signal handler. If sending an interrupt
  24   * from a signal handler is not necessary, the more lightweight \ref
  25   * CThreadInterrupt class can be used instead.
  26   */
  27  
  28  class SignalInterrupt
  29  {
  30  public:
  31      SignalInterrupt();
  32      explicit operator bool() const;
  33      [[nodiscard]] bool operator()();
  34      [[nodiscard]] bool reset();
  35      [[nodiscard]] bool wait();
  36  
  37  private:
  38      std::atomic<bool> m_flag;
  39  
  40  #ifndef WIN32
  41      // On UNIX-like operating systems use the self-pipe trick.
  42      TokenPipeEnd m_pipe_r;
  43      TokenPipeEnd m_pipe_w;
  44  #else
  45      // On windows use a condition variable, since we don't have any signals there
  46      std::mutex m_mutex;
  47      std::condition_variable m_cv;
  48  #endif
  49  };
  50  } // namespace util
  51  
  52  #endif // LIMENKA_UTIL_SIGNALINTERRUPT_H
  53