PATCH: async-sock-server.diff
Basic implementation of async IO queues in the server code for sockets.
Patch against: CVS-2002-04-12, with my sock-fd-type patch applied.
Modified files: server: sock.c
diff -ruNX ignore TMP/wine/server/sock.c MW/wine/server/sock.c --- TMP/wine/server/sock.c Fri Apr 12 14:38:16 2002 +++ MW/wine/server/sock.c Fri Apr 12 15:26:36 2002 @@ -86,6 +86,7 @@ static void sock_destroy( struct object *obj ); static int sock_get_error( int err ); static void sock_set_error(void); +static struct async_queue * sock_queue_async(struct object *obj, struct async* async, int type, int count);
static const struct object_ops sock_ops = { @@ -100,7 +101,7 @@ sock_get_fd, /* get_fd */ no_flush, /* flush */ sock_get_info, /* get_file_info */ - NULL, /* queue_async */ + sock_queue_async, /* queue_async */ sock_destroy /* destroy */ };
@@ -229,6 +230,21 @@ } } else { + + if ( sock->flags & WSA_FLAG_OVERLAPPED ) + { + if( IS_READY(sock->read_q) && (POLLIN & event) ) + { + if (debug_level) fprintf ( stderr, "activating read queue for socket %p\n", sock ); + async_notify(sock->read_q.head, STATUS_ALERTED); + } + if( IS_READY(sock->write_q) && (POLLOUT & event) ) + { + if (debug_level) fprintf ( stderr, "activating write queue for socket %p\n", sock ); + async_notify(sock->write_q.head, STATUS_ALERTED); + } + } + /* normal data flow */ if (event & POLLIN) { @@ -312,6 +328,8 @@ int ev = 0;
assert( obj->ops == &sock_ops ); + if ( debug_level ) + fprintf (stderr, "mask: %x %x %x -> %x\n", sock->mask, sock->state, sock->hmask, mask);
if (sock->state & FD_CONNECT) /* connecting, wait for writable */ @@ -320,8 +338,11 @@ /* listening, wait for readable */ return (sock->hmask & FD_ACCEPT) ? 0 : POLLIN;
- if (mask & FD_READ) ev |= POLLIN | POLLPRI; - if (mask & FD_WRITE) ev |= POLLOUT; + if (mask & FD_READ || (sock->flags & WSA_FLAG_OVERLAPPED && IS_READY (sock->read_q))) + ev |= POLLIN | POLLPRI; + if (mask & FD_WRITE || (sock->flags & WSA_FLAG_OVERLAPPED && IS_READY (sock->write_q))) + ev |= POLLOUT; + return ev; }
@@ -353,6 +374,38 @@ *flags = 0; if (sock->flags & WSA_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED; return FD_TYPE_DEFAULT; +} + +static struct async_queue *sock_queue_async(struct object *obj, struct async *async, int type, int count) +{ + struct sock *sock = (struct sock *)obj; + struct async_queue *q; + + assert( obj->ops == &sock_ops ); + + if ( !(sock->flags & WSA_FLAG_OVERLAPPED) ) + { + set_error ( STATUS_INVALID_HANDLE ); + return NULL; + } + + switch(type) + { + case ASYNC_TYPE_READ: + q = &sock->read_q; + break; + case ASYNC_TYPE_WRITE: + q = &sock->write_q; + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return NULL; + } + + if(async && !async->q) + async_insert(q, async); + + return q; }
static void sock_destroy( struct object *obj )