text: /*
   *  IXSelectInterruptEvent.cpp
   */
  
  //
  // On Windows we use a Windows Event to wake up ix::poll() (WSAWaitForMultipleEvents).
  // And on any other platform that doesn't support pipe file descriptors we
  // emulate the interrupt event by using a short timeout with ix::poll() and
  // read from the SelectInterrupt. (see Socket::poll() "Emulation mode")
  //
  #include "IXSelectInterruptEvent.h"
  
  namespace ix
  {
      SelectInterruptEvent::SelectInterruptEvent()
      {
  #ifdef _WIN32
          _event = CreateEvent(NULL, TRUE, FALSE, NULL);
  #endif
      }
  
      SelectInterruptEvent::~SelectInterruptEvent()
      {
  #ifdef _WIN32
          CloseHandle(_event);
  #endif
      }
  
      bool SelectInterruptEvent::init(std::string& /*errorMsg*/)
      {
          return true;
      }
  
      bool SelectInterruptEvent::notify(uint64_t value)
      {
          std::lock_guard<std::mutex> lock(_valuesMutex);
  
          // WebSocket implementation detail: We only need one of the values in the queue
          if (std::find(_values.begin(), _values.end(), value) == _values.end())
              _values.push_back(value);
  #ifdef _WIN32
          SetEvent(_event); // wake up
  #endif
          return true;
      }
  
      uint64_t SelectInterruptEvent::read()
      {
          std::lock_guard<std::mutex> lock(_valuesMutex);
  
          if (_values.size() > 0)
          {
              uint64_t value = _values.front();
              _values.pop_front();
  #ifdef _WIN32
              // signal the event if there is still data in the queue
              if (_values.size() == 0)
                  ResetEvent(_event);
  #endif
              return value;
          }
          return 0;
      }
  
      bool SelectInterruptEvent::clear()
      {
          std::lock_guard<std::mutex> lock(_valuesMutex);
          _values.clear();
  #ifdef _WIN32
          ResetEvent(_event);
  #endif
          return true;
      }
  
      void* SelectInterruptEvent::getEvent() const
      {
  #ifdef _WIN32
          return reinterpret_cast<void*>(_event);
  #else
          return nullptr;
  #endif
      }
  
  } // namespace ix
  