Linux の eventfd を Win32 イベントオブジェクトの SetEvent(), ResetEvent(), WaitForSingleObject() のように使いたかったので、やってみました。生成時に EFD_NONBLOCK を指定して、待機を select() で実施するのがポイントですね。
#include <sys/eventfd.h> #include <sys/select.h> #include <unistd.h> #include <cerrno> class Event { public: Event(): mEventFd(eventfd(0, EFD_NONBLOCK)) { } ~Event() { close(mEventFd); } int wait(int iTimeout) { fd_set aFds; FD_ZERO(&aFds); FD_SET(mEventFd, &aFds); timeval* aTimeoutP, aTimeout; if (iTimeout == -1) { aTimeoutP = nullptr; } else { aTimeout.tv_sec = iTimeout / 1000; aTimeout.tv_usec = (iTimeout % 1000) * 1000; aTimeoutP = &aTimeout; } return select(mEventFd + 1, &aFds, nullptr, nullptr, aTimeoutP); } int set() { return eventfd_write(mEventFd, 1); } int reset() { eventfd_t aValue; auto aResult = eventfd_read(mEventFd, &aValue); if ((aResult == -1) && (errno == EAGAIN)) { aResult = 0; } return aResult; } private: int mEventFd; }; // test #include <cstdio> int main() { Event aEvent; printf("Event::wait(0) = %d : 0\n", aEvent.wait(0)); printf("Event::set() = %d : 0\n", aEvent.set()); printf("Event::wait(-1) = %d : 1\n", aEvent.wait(-1)); printf("Event::wait(0) = %d : 1\n", aEvent.wait(0)); printf("Event::reset() = %d : 0\n", aEvent.reset()); printf("Event::wait(0) = %d : 0\n", aEvent.wait(0)); printf("Event::reset() = %d : 0\n", aEvent.reset()); return 0; }
余談ですが、WSL を初めて使いました。apt も使えてとても便利ですね。これで Cygwin / MSYS2 も卒業かな。