Yup, though eventfd is (annoyingly) half-way between an automatic and a manual-reset event. Like auto-reset you can test and reset with a single system call (read(), which can be either blocking or non-blocking). If you use poll() however they are more like manual-reset.
Writing code that is portable between POSIX and Win32 is not easy. Libraries such as this one can be useful, but it's even better if you let both OSes teach you some tricks, sometimes porting POSIX features to Win32 and sometimes the other way round.
For example, manual-reset events are actually a pretty nifty replacement for condition variables in lock-free code. However you can't use them directly because SetEvent/ResetEvent are too heavy-weight in Win32, going down to the kernel even if there's no waiter. So after reimplementing manual-reset events in POSIX, you can apply the lessons you learnt to speed up Win32 as well.
For QEMU we have two very different portability wrappers for Win32 events. One is inspired by eventfd (it uses manual-reset events on Windows and pipes on POSIX systems other than Linux) and is used together with poll() on POSIX systems and WaitForMultipleObjects on Win32 systems. The second is a single-process version of the manual reset event with a fast userspace-only fast path; on POSIX it uses futexes, while on Win32 it uses a manual-reset event but it wraps it to skip as many system calls as possible. Resetting the event in fact doesn't ever go to the kernel (the Win32 code calls ResetEvent just before waiting, it's a bit tricky but not racy).
Another little-known trick we use in QEMU is combining WSAEventSelect, select() and WaitForMultipleObjects to achieve level-triggered polling of sockets and other file descriptors; because we have a bunch of legacy network code we cannot use edge-triggered epoll or WSAEventSelect (on Windows, select is level triggered but only works with sockets; WSAEventSelect and WaitForMultipleObjects are edge triggered but work with other file descriptors). The socket portability codein glib is insanely complicated; it creates a thread per socket, buffers all I/O, and uses a bunch of events for synchronization. In QEMU it was just 100 or so lines of code. Winsock is still a pain for portability, especially if you care about performance a lot, but with the right tricks it's manageable.
Writing code that is portable between POSIX and Win32 is not easy. Libraries such as this one can be useful, but it's even better if you let both OSes teach you some tricks, sometimes porting POSIX features to Win32 and sometimes the other way round.
For example, manual-reset events are actually a pretty nifty replacement for condition variables in lock-free code. However you can't use them directly because SetEvent/ResetEvent are too heavy-weight in Win32, going down to the kernel even if there's no waiter. So after reimplementing manual-reset events in POSIX, you can apply the lessons you learnt to speed up Win32 as well.
For QEMU we have two very different portability wrappers for Win32 events. One is inspired by eventfd (it uses manual-reset events on Windows and pipes on POSIX systems other than Linux) and is used together with poll() on POSIX systems and WaitForMultipleObjects on Win32 systems. The second is a single-process version of the manual reset event with a fast userspace-only fast path; on POSIX it uses futexes, while on Win32 it uses a manual-reset event but it wraps it to skip as many system calls as possible. Resetting the event in fact doesn't ever go to the kernel (the Win32 code calls ResetEvent just before waiting, it's a bit tricky but not racy).
Another little-known trick we use in QEMU is combining WSAEventSelect, select() and WaitForMultipleObjects to achieve level-triggered polling of sockets and other file descriptors; because we have a bunch of legacy network code we cannot use edge-triggered epoll or WSAEventSelect (on Windows, select is level triggered but only works with sockets; WSAEventSelect and WaitForMultipleObjects are edge triggered but work with other file descriptors). The socket portability codein glib is insanely complicated; it creates a thread per socket, buffers all I/O, and uses a bunch of events for synchronization. In QEMU it was just 100 or so lines of code. Winsock is still a pain for portability, especially if you care about performance a lot, but with the right tricks it's manageable.