#3 in series (incremental) Patch file: 003-sock_basic.diff Purpose: Basic implementation of socket flags. Created: 2002-01-07 Applies: CVS 2002-01-07 (with 002-fd_type.diff applied) This patch adds socket flags to the server data structure for sockets, and adds means to set these flags when creating sockets. It also provides basic server functionality to allow async I/O on sockets. ** NOTE ON BUILDING: tools/make_requests must be run ** ** after applying this patch ** server/protocol.def: create_socket request: add flags parameter. server/sock.c: struct socket: add flags field. add struct async_queue fields for async IO operations. sock_get_info(): Account for WSA_FLAG_OVERLAPPED. create_socket(): Additional parameter (unsigned int flags) Initialize async queues for overlapped sockets. create_socket_req(): Pass flags parameter to create_socket(). sock_destroy(): Destroy async queues for overlapped sockets. dlls/winsock/socket.c: WS_socket(): Initialize socket flags parameter (currently 0). Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com> diff -ru -X diffignore CVS/wine/dlls/winsock/socket.c MW/wine/dlls/winsock/socket.c --- CVS/wine/dlls/winsock/socket.c Wed Jan 2 12:50:02 2002 +++ MW/wine/dlls/winsock/socket.c Fri Jan 4 11:13:03 2002 @@ -2381,6 +2381,7 @@ req->type = type; req->protocol = protocol; req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; + req->flags = 0U; req->inherit = TRUE; set_error( wine_server_call( req ) ); ret = (SOCKET)reply->handle; diff -ru -X diffignore CVS/wine/server/file.c MW/wine/server/file.c --- CVS/wine/server/file.c Fri Jan 4 11:07:45 2002 +++ MW/wine/server/file.c Thu Jan 3 15:21:50 2002 @@ -342,7 +342,7 @@ reply->serial = 0; /* FIXME */ } - if (file->flags & FILE_FLAG_OVERLAPPED) + if ( file->flags & FILE_FLAG_OVERLAPPED ) fd_type |= FD_TYPE_FLAG_OVERLAPPED; return fd_type; diff -ru -X diffignore CVS/wine/server/protocol.def MW/wine/server/protocol.def --- CVS/wine/server/protocol.def Fri Jan 4 11:07:45 2002 +++ MW/wine/server/protocol.def Fri Jan 4 10:20:53 2002 @@ -646,6 +646,7 @@ int family; /* family, see socket manpage */ int type; /* type, see socket manpage */ int protocol; /* protocol, see socket manpage */ + unsigned int flags; /* socket flags */ @REPLY handle_t handle; /* handle to the new socket */ @END diff -ru -X diffignore CVS/wine/server/sock.c MW/wine/server/sock.c --- CVS/wine/server/sock.c Fri Jan 4 11:07:45 2002 +++ MW/wine/server/sock.c Fri Jan 4 11:10:45 2002 @@ -36,6 +36,7 @@ #include "handle.h" #include "thread.h" #include "request.h" +#include "async.h" /* To avoid conflicts with the Unix socket headers. Plus we only need a few * macros anyway. @@ -50,8 +51,11 @@ unsigned int mask; /* event mask */ unsigned int hmask; /* held (blocked) events */ unsigned int pmask; /* pending events */ + unsigned int flags; /* socket flags */ struct event *event; /* event object */ int errors[FD_MAX_EVENTS]; /* event errors */ + struct async_queue read_q; /* Queue for asynchronous reads */ + struct async_queue write_q; /* Queue for asynchronous writes */ }; static void sock_dump( struct object *obj, int verbose ); @@ -275,6 +279,9 @@ static int sock_get_info( struct object *obj, struct get_file_info_reply *reply ) { + struct sock *sock = (struct sock*) obj; + assert ( obj->ops == &sock_ops ); + if (reply) { reply->type = FILE_TYPE_PIPE; @@ -288,6 +295,10 @@ reply->index_low = 0; reply->serial = 0; } + + if ( sock->flags & WSA_FLAG_OVERLAPPED ) + return FD_TYPE_SOCKET | FD_TYPE_FLAG_OVERLAPPED; + return FD_TYPE_SOCKET; } @@ -297,6 +308,13 @@ assert( obj->ops == &sock_ops ); /* FIXME: special socket shutdown stuff? */ + + if ( sock->flags & WSA_FLAG_OVERLAPPED ) + { + destroy_async_queue ( &sock->read_q ); + destroy_async_queue ( &sock->write_q ); + } + if (sock->event) { /* if the service thread was waiting for the event object, @@ -310,7 +328,7 @@ } /* create a new and unconnected socket */ -static struct object *create_socket( int family, int type, int protocol ) +static struct object *create_socket( int family, int type, int protocol, unsigned int flags ) { struct sock *sock; int sockfd; @@ -329,9 +347,15 @@ sock->mask = 0; sock->hmask = 0; sock->pmask = 0; + sock->flags = flags; sock->event = NULL; sock_reselect( sock ); clear_error(); + if (sock->flags & WSA_FLAG_OVERLAPPED) + { + init_async_queue (&sock->read_q); + init_async_queue (&sock->write_q); + } return &sock->obj; } @@ -377,6 +401,12 @@ acceptsock->event = NULL; if (sock->event && !(sock->mask & FD_WINE_SERVEVENT)) acceptsock->event = (struct event *)grab_object( sock->event ); + acceptsock->flags = sock->flags; + if ( acceptsock->flags & WSA_FLAG_OVERLAPPED ) + { + init_async_queue ( &acceptsock->read_q ); + init_async_queue ( &acceptsock->write_q ); + } sock_reselect( acceptsock ); clear_error(); @@ -463,7 +493,7 @@ struct object *obj; reply->handle = 0; - if ((obj = create_socket( req->family, req->type, req->protocol )) != NULL) + if ((obj = create_socket( req->family, req->type, req->protocol, req->flags )) != NULL) { reply->handle = alloc_handle( current->process, obj, req->access, req->inherit ); release_object( obj );