>> I now need to finish the test/example application.
>> When that's done, I'll upload.  Might even be this weekend.

I've been working away.  Got a wierd bug which is holding things up.

>> 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) );

> It looks to me like all your callbacks are asynchronous.

Yes.

> Is that the case? If so you're probably working off the standard iocp
example code which spawns num_cpus/2 or num_cpus*2 or
> f(num_cpus) threads,

Yup, CPU count * 2.

> however that's the sort of choice that
> I think should be left to user, exposing instead an interface
> int iocp_wait(long timeout) which calls the callbacks.

Do you mean that the user goes off in his code, does his stuff, and when
he's ready to deal with IOCP stuff, he calls iocp_wait() and the API is
then  free to call the callbacks, but it will be using the users thread to
do this, and after "long timeout" has expired, iocp_wait() returns and the
user continues with his code till he next calls iocp_wait()?

> This
> lets the user choose the "asynchronicity" of their app,
> i.e. they can write singlethreaded mutex-less iocp code.

Would it be possible to have a single threaded app which is trying to do
C10K?

> As an interface socket_iocp_new is a tiny bit "busy" as it
> wraps almost every function that iocps understand.

Yes.  In fact, it's the longest prototype I've ever written.  OTOH, when
you actually write it, it's only six arguments.

> A bit of
> factoring might make it more friendly. A control-block style
> interface could also help as it cuts down the argument list
> and makes the "per socket user state" implicit (it actually
> makes it per iocp operation user state). It also gives you
> two way communication (user -> iocp library -> user in callback)
>
> typedef struct {
>       SOCKET  s;      /* <- */
>       char*   buf;    /* <-, -> */
>       long    nbytes; /* <-, -> */
>       void (*iocp_read_callback)(iocp_state* st, iocp_read*
control_block); /*
> <- */
> } iocp_read;
>
> The user can piggy back per operation data like so:
> typedef struct {
>       iocp_read       control_block;
>       /* extra stuff here */
> }my_iocp_read;
>
> void
> my_iocp_read_callback)(iocp_state* st, iocp_read* control_block) {
>       my_iocp_read* my_cb = (my_iocp_read*)control_block;
>       /* respond, requeue, whatever */
> }

This converts a large one-off complexity in the new() function into a
smaller complexity which is required for every function call.

Separately, ould it be useful to have per read state in the way that per
write state exists?  it seems to me since that reads are serial (only one
read at a time per socket) that state will be kept by the user in the per
socket state.


_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users

Reply via email to