This commit is contained in:
Ryan Dahl 2011-03-23 01:39:59 -07:00
commit 133b4e3999
3 changed files with 145 additions and 0 deletions

68
iocp-links.html Normal file
View File

@ -0,0 +1,68 @@
<style>
body {
width: 30em;
font-size: 12pt;
font-family: Arial;
max-width: 30em;
margin: 1em;
}
</style>
<h1>Asynchronous I/O in Windows for UNIX Programmers</h1>
<p>Windows has very different notions for how asynchronous and non-blocking I/O
are done. While Windows does have <code>select()</code>, it is severely
limited: it supports only 64 file descriptors. (Does <code>select()</code>
work on named pipes in windows?) Windows has the possibility of serving
20,000 TCP connections using a different API called <a
href="http://msdn.microsoft.com/en-us/library/ms686358(v=vs.85).aspx">overlapped
I/O</a> using <a
href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx">I/O
completion ports</a>. Unfortunately I/O completion ports
tips
<ul>
<li> overlapped = non-blocking.
<li> There is no overlapped <a href="http://msdn.microsoft.com/en-us/library/ms738518(VS.85).aspx"><code>GetAddrInfoEx()</code></a> function. It seems Asynchronous Procedure Calls must be used instead.
<li> <a href=http://msdn.microsoft.com/en-us/library/ms740673(VS.85).aspx"><code>Windows Sockets 2</code></a>
</ul>
IOCP:
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms686358(v=vs.85).aspx">Synchronization and Overlapped Input and Output</a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms741665(v=VS.85).aspx"><code>WSAOVERLAPPED</code> Structure</a>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms683209(v=VS.85).aspx"><code>GetOverlappedResult()</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms683244(v=VS.85).aspx"><code>HasOverlappedIoCompleted()</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/aa363792(v=vs.85).aspx"><code>CancelIoEx()</code></a>
&mdash; cancels an overlapped operation.
</ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms742203(v=vs.85).aspx"><code>WSASend()</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms741688(v=VS.85).aspx"><code>WSARecv()</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms737606(VS.85).aspx"><code>ConnectEx()</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms740565(v=VS.85).aspx"><code>TransmitFile()</code></a>
&mdash; an async <code>sendfile()</code> for windows.
<li><a href="http://msdn.microsoft.com/en-us/library/ms741565(v=VS.85).aspx"><code>WSADuplicateSocket()</code></a>
&mdash; describes how to share a socket between two processes.
</ul>
APC:
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms681951(v=vs.85).aspx">Asynchronous Procedure Calls</a>
<li><a href="http://msdn.microsoft.com/en-us/library/ms682016"><code>DNSQuery()</code></a>
&mdash; General purpose DNS query function like <code>res_query()</code> on UNIX.
</ul>
Pipes:
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa365781(v=VS.85).aspx"><code>Pipe functions</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx"><code>CreateNamedPipe</code></a>
<li><a href="http://msdn.microsoft.com/en-us/library/aa365144(v=VS.85).aspx"><code>CallNamedPipe</code></a>
&mdash; like <code>accept</code> is for UNIX pipes.
<li><a href="http://msdn.microsoft.com/en-us/library/aa365146(v=VS.85).aspx"><code>ConnectNamedPipe</code></a>
</ul>

74
ol.h Normal file
View File

@ -0,0 +1,74 @@
#ifdef windows
# include "ol_win.h"
#else
# include "ol_unix.h"
#endif
typedef ol_read_cb void(*)(ol_buf *bufs, int bufcnt);
typedef ol_close_cb void(*)(int read, int write);
typedef ol_connect_cb void(*)();
typedef ol_connect_cb void(*)();
typedef enum {
OL_NAMED_PIPE,
OL_TCP,
OL_TCP6
} ol_socket_type;
typedef struct {
size_t len;
char* buf;
} ol_buf;
typedef struct {
size_t len;
void* name;
} ol_addr;
/**
* Creates a new socket of given type. If bind_addr is NULL a random
* port will be bound in the case of OL_TCP and OL_TCP6. In the case
* of NAMED_PIPE, bind_addr specifies a string describing the location
* to bind to.
*/
ol_socket* ol_socket_create(ol_socket_type type, ol_buf* bind_addr,
ol_read_cb cb, ol_close_cb cb);
int ol_socket_connect(ol_socket* socket, ol_addr addr,
ol_buf* buf, size_t* bytes_sent, ol_connect_cb ol);
int ol_socket_pause(ol_socket* socket);
int ol_socket_resume(ol_socket* socket);
int ol_socket_address(ol_socket* socket, ol_addr* addr);
/**
* Send data to socket. User responsible for bufs until callback is made.
* Multiple ol_socket_write() calls may be issued before the previous ones
* complete - data will sent in the correct order.
*/
int ol_socket_write(ol_socket* socket, ol_buf* bufs, int bufcnt,
size_t* bytes_sent, ol_write_cb cb);
int ol_socket_listen(ol_socket* server, int backlog, ol_accept_cb cb);
int ol_socket_shutdown_write(ol_socket* socket);
int ol_socket_close(ol_socket* socket);
int ol_socket_free(ol_socket* socket);

3
ol_win.c Normal file
View File

@ -0,0 +1,3 @@
#include "ol.h"
void ol_init