Windows IOCP provides a way to scalable and high performance Input/Output. It also gives an easier way to make a event loop or message passing system, take a look of the demo bellow.
#include <iostream>
#include <sstream>
#include <string>
#include <thread>
#include <ctime>
#include <windows.h>
template<typename ctor, typename dtor, typename T>
class scoped_object
{
public:
scoped_object(ctor c, dtor d): t_(c()), dtor_(d){}
~scoped_object()
{
dtor_(t_);
}
operator T& ()
{
return t_;
}
private:
scoped_object(scoped_object const&) = delete;
scoped_object& operator=(scoped_object const&) = delete;
T t_;
dtor dtor_;
};
#define def_scoped_object(ctor, dtor, obj) \
scoped_object<decltype(ctor), decltype(dtor), decltype(ctor())> obj(ctor, dtor);
int main()
{
auto completionPortCtor = [](){return CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,0, 1);};
auto completionPortDtor = [](HANDLE h){ CloseHandle(h);};
def_scoped_object(completionPortCtor, completionPortDtor,completionPort);
std::thread worker([&completionPort](){
DWORD numberOfBytes;
ULONG_PTR completionKey;
LPOVERLAPPED lpOverLapped;
while(GetQueuedCompletionStatus(completionPort, &numberOfBytes, &completionKey, &lpOverLapped, INFINITE) )
{
std::string* msg = (std::string*)(lpOverLapped);
if(!msg) break;
time_t now = time(NULL);
std::cout << "[" << now << "] process msg [" << *msg << "]"<< std::endl;
delete msg;
}
});
for(int i = 5; i > -1; --i)
{
std::ostringstream oss;
time_t now = time(NULL);
oss <<" produces " << i << " at " << now;
std::string * msg = new std::string(oss.str());
Sleep(1550);
PostQueuedCompletionStatus(completionPort, i, 0, (OVERLAPPED*)msg);
}
PostQueuedCompletionStatus(completionPort, 0, 0, NULL);
worker.join();
return 0;
}