[Libevent-users] IOCP API

Toby Douglass toby.douglass at summerblue.net
Fri Feb 23 18:43:11 EST 2007


Okay, so I've finished writing the IOCP code.

I now need to finish the test/example application.

When that's done, I'll upload.  Might even be this weekend.

Prototypes
==========
1. int socket_iocp_new( void **socket_iocp_state, size_t 
read_buffer_size, void (*accept_callback_function)(SOCKET socket, struct 
sockaddr *local_address, struct sockaddr *remote_address, void 
*listen_socket_user_state, void **per_socket_user_state), void 
(*recv_callback_function)(SOCKET socket, void *read_buffer, DWORD 
byte_count, void *per_socket_user_state), void 
(*send_callback_function)( SOCKET socket, void *per_socket_user_state, 
void *per_write_user_state ), void (*error_callback_function)(SOCKET 
socket, void *per_socket_user_state) );

2. void socket_iocp_delete( void *socket_iocp_state );

3. int socket_iocp_add_listen_socket( void *socket_iocp_state, SOCKET 
socket, size_t accept_socket_backlog, void *listen_user_state );

4. int socket_iocp_add_connected_socket( void *socket_iocp_state, SOCKET 
socket, void *per_socket_user_state );

5. int socket_iocp_issue_recv( void *socket_iocp_state, void 
*socket_iocp_socket_state );

6. int socket_iocp_issue_sync_send( void *socket_iocp_state, void 
*socket_iocp_socket_state, void *write_buffer, DWORD 
number_bytes_to_write, void *per_write_user_state );

7. int socket_iocp_issue_async_send( void *socket_iocp_state, void 
*socket_iocp_socket_state, void *write_buffer, DWORD 
number_bytes_to_write, void *per_write_user_state );

API Useage
==========
First, call socket_iocp_new().  This returns the basic state the API 
uses.  Each state represents a single IOCP object.  When calling this 
function, you pass in four callback functions; one for accept, one for 
send, one for recv and one for error.

Once you have this state, you can then add either listen sockets or 
connected sockets to the IOCP.

If you add a listen socket, you specify how many ready sockets should be 
kept allocated on that listen socket.  The API maintains that number of 
ready sockets.

When an incoming connection occurs, the accept callback is called.  At 
this point, the user can associate state of his own with that socket.

If you add a connected socket, it's simply added to the IOCP.  The user 
can pass in his own state to be associated with that socket.

Sockets, once added, have no reads or writes issued on them; they'll do 
nothing until the user issues one of three IOCP send/recv functions in 
the API.

The user can issue the IOCP API recv function on a socket.  When that 
recv completes, the recv callback is called with the read buffer and the 
user's state.  The user must call the IOCP recv function again for 
another read to be present and ready and outstanding on that socket.

The user can issue either a "synchronous" or "asynchronous" write on a 
socket.

A sync write requires no malloc, but requires the user to ensure he only 
has one write occurring at a time on a socket; he cannot issue another 
write until the current write has completed.  When the write is issued, 
the user can provide state for that write.  When the write completes, 
the write complete function is called, with both the state the user 
associated with that socket and the state the user associated with that 
write.

An async write requires one malloc per call and permits the user to have 
an arbitrary number of concurrent writes occurring on a single socket. 
As with the sync write, the user can pass in a per-write state, and when 
a write completes, the write callback is called, with the state the user 
associated with the socket and the state associated with that write.

Overall Usage
=============
The idea is that the user calls the new() function once at program init. 
  Then the user adds/removes sockets as necessary, and issues 
reads/writes as necessary, and services those reads/writes in the 
callback functions, using the per socket/per write state information.

The user has to issue a new read on a socket, in the read callback, to 
continue reading from a socket.

So there you go!

Comments and thoughts, please.


More information about the Libevent-users mailing list