[Libevent-users] Integrate Windows I/O Completion Port into Libevent
liusifan
liusifan at gmail.com
Sun Jun 1 01:51:53 EDT 2008
Integrate Windows I/O Completion Port into Libevent
IOCP is true async i/o model, and libevent is event-driven i/o model.
1. How to emulate event-driven recv/send ?
It is possible to use IOCP to emulate event-driven mode. When you make read or write calls, pass in a zero-byte buffer (ie, you can manage your i/o buffers using event driven semantics). So if you issue a read passing in a zero-byte length buffer, your will get notified when there is data to read.
2. How to emulate event-driven accept ?
The WSAEventSelect API provides an event-driven accept mechanism.
3. How to integrate these two mechanism ?
When we issue a WSARecv or WSASend, we need to pass a OVERLAPPED structure. This structure has a hEvent member.
http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx
If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.
We could use one event for all WSARecv/WSASend.
http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx
Setting an event that is already set has no effect.
So it is possible to use WSAWaitForMultipleEvents to integrate IOCP and WSAEventSelect.
4. Solution
/* objects[0] for iocp operations, object[1..63] for accept */
HANDLE objects[64];
struct event * accepts[64];
struct win32iocp_event event1;
event1.overlapped.hEvent = objects[0];
WSARecv( ..., &event1.overlapped, ... );
....
struct win32iocp_event event2;
event2.overlapped.hEvent = objects[0];
WSASend( ..., &event2.overlapped, ... );
...
WSAEventSelect( ev1->ev_fd, objects[1], FD_ACCEPT );
accepts[1] = ev1;
...
WSAEventSelect( ev2->ev_fd, objects[2], FD_ACCEPT );
accepts[2] = ev2;
...
int index = WSAWaitForMultipleEvents( 64, objects, FALSE, timeout, FALSE );
index = index - WSA_WAIT_EVENT_0;
if( index > 0 ) {
struct event * event = win32iocp_op->accepts[index];
event_active (event, EV_READ | EV_ACCEPT, 1);
}
if( index == 0 ) {
for( ; ; ) {
GetQueuedCompletionPort( ...... );
}
}
5. Limitation
It can only support 63 accept fds.
6. Source code
http://spserver.googlecode.com/files/libevent-1.4.4-iocp.zip
diff file : libevent-1.4.4-iocp\libevent-iocp\diff.txt
add file : libevent-1.4.4-iocp\WIN32-Code\win32iocp.cpp
liusifan
2008-06-01
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://monkeymail.org/archives/libevent-users/attachments/20080601/b4b86372/attachment.htm
More information about the Libevent-users
mailing list