<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=GB2312">
<META content="MSHTML 6.00.2900.3314" name=GENERATOR>
<STYLE>BLOCKQUOTE {
        MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; MARGIN-LEFT: 2em
}
OL {
        MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px
}
UL {
        MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px
}
</STYLE>
</HEAD>
<BODY
style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px">
<DIV><FONT face=Verdana><FONT size=2>Integrate Windows I/O Completion Port into
Libevent</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>IOCP is true async i/o model, and libevent
is event-driven i/o model.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>1. How to emulate event-driven recv/send
?<BR>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.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>2. How to emulate event-driven accept
?<BR>The WSAEventSelect API provides an event-driven accept
mechanism.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>3. How to integrate these two mechanism
?<BR>When we issue a WSARecv or WSASend, we need to pass a OVERLAPPED structure.
This structure has a hEvent member.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2><A
href="http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx</A><BR>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.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>We could use one event for all
WSARecv/WSASend.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2><A
href="http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx</A><BR>Setting
an event that is already set has no effect.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>So it is possible to use
WSAWaitForMultipleEvents to integrate IOCP and
WSAEventSelect.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>4. Solution</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>/* objects[0] for iocp operations,
object[1..63] for accept */<BR>HANDLE objects[64];<BR>struct event *
accepts[64];</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>struct win32iocp_event
event1;<BR>event1.overlapped.hEvent = objects[0];<BR>WSARecv( ...,
&event1.overlapped, ... );<BR>....</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>struct win32iocp_event
event2;<BR>event2.overlapped.hEvent = objects[0];<BR>WSASend( ...,
&event2.overlapped, ... );<BR>...</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>WSAEventSelect( ev1->ev_fd, objects[1],
FD_ACCEPT );<BR>accepts[1] = ev1;<BR>...</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>WSAEventSelect( ev2->ev_fd, objects[2],
FD_ACCEPT );<BR>accepts[2] = ev2;<BR>...</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>int index = WSAWaitForMultipleEvents( 64,
objects, FALSE, timeout, FALSE );<BR>index = index -
WSA_WAIT_EVENT_0;</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>if( index > 0 ) {<BR> struct event
* event = win32iocp_op->accepts[index];<BR> event_active (event, EV_READ
| EV_ACCEPT, 1);<BR>}</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>if( index == 0 ) {<BR> for( ; ; )
{<BR> GetQueuedCompletionPort( ......
);<BR> }<BR>}</FONT></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2>5. Limitation<BR>It can only support 63
accept fds.</FONT></FONT></DIV>
<DIV> </DIV>
<DIV>6. Source code</DIV>
<DIV><A
href="http://spserver.googlecode.com/files/libevent-1.4.4-iocp.zip">http://spserver.googlecode.com/files/libevent-1.4.4-iocp.zip</A></DIV>
<DIV>diff file : libevent-1.4.4-iocp\libevent-iocp\diff.txt</DIV>
<DIV>add file : libevent-1.4.4-iocp\WIN32-Code\win32iocp.cpp</DIV>
<DIV> </DIV>
<DIV><FONT face=Verdana><FONT size=2></FONT> </DIV>
<DIV><FONT size=2></FONT> </DIV>
<DIV align=left><FONT size=2>
<HR style="WIDTH: 122px; HEIGHT: 2px" SIZE=2>
</FONT></DIV>
<DIV><FONT color=#c0c0c0><FONT size=2><SPAN>liusifan</SPAN></FONT></DIV>
<DIV><FONT size=2>2008-06-01</FONT></FONT></DIV></FONT></BODY></HTML>