BSD and Solaris (which also has kqueue, and something else IIRC) got this really right while Linux got this really wrong.
I still prefer NT's IOCP, but kqueue isn't bad. epoll… is what happens when you get someone who's never done asynchronous I/O to design a system for doing asynchronous I/O.
NT's IOCP is good, sensible model overall having used it some recently. It's mildly put off by some "gotchas" (like async calls occasionally returning synchronously if there's nothing else on the queue, so you have to be careful with send, recv, etc), but the actual design is good. Thread pools being a convenient, native API in Vista+ is also a bonus.
I still prefer NT's IOCP, but kqueue isn't bad. epoll… is what happens when you get someone who's never done asynchronous I/O to design a system for doing asynchronous I/O.