Asynchronous Named Pipes

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Asynchronous Named Pipes

Robert Shearman
Hi,

This patch depends on "Small RPC Bug Fixes" for the ole32 tests to pass.

Changelog:
Implement overlapped I/O with named pipes.

--
Rob Shearman


Index: dlls/ntdll/file.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/file.c,v
retrieving revision 1.89
diff -u -p -r1.89 file.c
--- dlls/ntdll/file.c 26 May 2005 16:07:53 -0000 1.89
+++ dlls/ntdll/file.c 7 Jun 2005 21:00:00 -0000
@@ -158,6 +158,7 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE ha
         SERVER_START_REQ( open_named_pipe )
         {
             req->access = access;
+            req->flags = options;
             req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
             wine_server_add_data( req, attr->ObjectName->Buffer + 4,
                                   attr->ObjectName->Length - 4*sizeof(WCHAR) );
Index: include/wine/server_protocol.h
===================================================================
RCS file: /home/wine/wine/include/wine/server_protocol.h,v
retrieving revision 1.140
diff -u -p -r1.140 server_protocol.h
--- include/wine/server_protocol.h 31 May 2005 13:37:16 -0000 1.140
+++ include/wine/server_protocol.h 7 Jun 2005 21:00:05 -0000
@@ -2402,6 +2402,7 @@ struct open_named_pipe_request
 {
     struct request_header __header;
     unsigned int   access;
+    unsigned int   flags;
     int            inherit;
     /* VARARG(name,unicode_str); */
 };
@@ -3998,6 +3999,6 @@ union generic_reply
     struct set_mailslot_info_reply set_mailslot_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 177
+#define SERVER_PROTOCOL_VERSION 178
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
Index: server/named_pipe.c
===================================================================
RCS file: /home/wine/wine/server/named_pipe.c,v
retrieving revision 1.39
diff -u -p -r1.39 named_pipe.c
--- server/named_pipe.c 25 May 2005 18:41:09 -0000 1.39
+++ server/named_pipe.c 7 Jun 2005 21:00:06 -0000
@@ -44,6 +44,8 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "winreg.h"
+#include "winternl.h"
 
 #include "file.h"
 #include "handle.h"
@@ -73,6 +75,7 @@ struct pipe_server
     struct timeout_user *flush_poll;
     struct event        *event;
     struct list          wait_q;     /* only a single one can be queued */
+    unsigned int         options;    /* pipe options */
 };
 
 struct pipe_client
@@ -80,6 +83,7 @@ struct pipe_client
     struct object        obj;        /* object header */
     struct fd           *fd;         /* pipe file descriptor */
     struct pipe_server  *server;     /* server that this client is connected to */
+    unsigned int         flags;      /* file flags */
 };
 
 struct named_pipe
@@ -111,15 +115,12 @@ static const struct object_ops named_pip
     named_pipe_destroy            /* destroy */
 };
 
-/* common to clients and servers */
-static int pipe_end_get_poll_events( struct fd *fd );
-static int pipe_end_get_info( struct fd *fd );
-
 /* server end functions */
 static void pipe_server_dump( struct object *obj, int verbose );
 static struct fd *pipe_server_get_fd( struct object *obj );
 static void pipe_server_destroy( struct object *obj);
 static int pipe_server_flush( struct fd *fd, struct event **event );
+static int pipe_server_get_info( struct fd *fd );
 
 static const struct object_ops pipe_server_ops =
 {
@@ -136,12 +137,12 @@ static const struct object_ops pipe_serv
 
 static const struct fd_ops pipe_server_fd_ops =
 {
-    pipe_end_get_poll_events,     /* get_poll_events */
+    default_fd_get_poll_events,     /* get_poll_events */
     default_poll_event,           /* poll_event */
     pipe_server_flush,            /* flush */
-    pipe_end_get_info,            /* get_file_info */
-    no_queue_async,               /* queue_async */
-    no_cancel_async,              /* cancel_async */
+    pipe_server_get_info,         /* get_file_info */
+    default_fd_queue_async,       /* queue_async */
+    default_fd_cancel_async,      /* cancel_async */
 };
 
 /* client end functions */
@@ -149,6 +150,7 @@ static void pipe_client_dump( struct obj
 static struct fd *pipe_client_get_fd( struct object *obj );
 static void pipe_client_destroy( struct object *obj );
 static int pipe_client_flush( struct fd *fd, struct event **event );
+static int pipe_client_get_info( struct fd *fd );
 
 static const struct object_ops pipe_client_ops =
 {
@@ -165,12 +167,12 @@ static const struct object_ops pipe_clie
 
 static const struct fd_ops pipe_client_fd_ops =
 {
-    pipe_end_get_poll_events,     /* get_poll_events */
+    default_fd_get_poll_events,   /* get_poll_events */
     default_poll_event,           /* poll_event */
     pipe_client_flush,            /* flush */
-    pipe_end_get_info,            /* get_file_info */
-    no_queue_async,               /* queue_async */
-    no_cancel_async               /* cancel_async */
+    pipe_client_get_info,         /* get_file_info */
+    default_fd_queue_async,       /* queue_async */
+    default_fd_cancel_async       /* cancel_async */
 };
 
 static void named_pipe_dump( struct object *obj, int verbose )
@@ -330,11 +332,6 @@ static void pipe_client_destroy( struct
     assert( !client->fd );
 }
 
-static int pipe_end_get_poll_events( struct fd *fd )
-{
-    return POLLIN | POLLOUT;  /* FIXME */
-}
-
 static int pipe_data_remaining( struct pipe_server *server )
 {
     struct pollfd pfd;
@@ -417,9 +414,29 @@ static int pipe_client_flush( struct fd
     return 0;
 }
 
-static int pipe_end_get_info( struct fd *fd )
+static inline int is_overlapped( unsigned int options )
 {
-    return 0;
+    return !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
+}
+
+static int pipe_server_get_info( struct fd *fd )
+{
+    struct pipe_server *server = get_fd_user( fd );
+    int flags = FD_FLAG_AVAILABLE;
+
+    if (is_overlapped( server->options )) flags |= FD_FLAG_OVERLAPPED;
+
+    return flags;
+}
+
+static int pipe_client_get_info( struct fd *fd )
+{
+    struct pipe_client *client = get_fd_user( fd );
+    int flags = FD_FLAG_AVAILABLE;
+
+    if (is_overlapped( client->flags )) flags |= FD_FLAG_OVERLAPPED;
+
+    return flags;
 }
 
 static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
@@ -463,7 +480,7 @@ static struct pipe_server *get_pipe_serv
     return (struct pipe_server *) obj;
 }
 
-static struct pipe_server *create_pipe_server( struct named_pipe *pipe )
+static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options )
 {
     struct pipe_server *server;
 
@@ -476,6 +493,7 @@ static struct pipe_server *create_pipe_s
     server->state = ps_idle_server;
     server->client = NULL;
     server->flush_poll = NULL;
+    server->options = options;
     list_init( &server->wait_q );
 
     list_add_head( &pipe->servers, &server->entry );
@@ -484,7 +502,7 @@ static struct pipe_server *create_pipe_s
     return server;
 }
 
-static struct pipe_client *create_pipe_client( struct pipe_server *server )
+static struct pipe_client *create_pipe_client( struct pipe_server *server, unsigned int flags )
 {
     struct pipe_client *client;
 
@@ -494,6 +512,7 @@ static struct pipe_client *create_pipe_c
 
     client->fd = NULL;
     client->server = server;
+    client->flags = flags;
 
     return client;
 }
@@ -559,7 +578,7 @@ DECL_HANDLER(create_named_pipe)
         }
     }
 
-    server = create_pipe_server( pipe );
+    server = create_pipe_server( pipe, req->options );
     if(server)
     {
         reply->handle = alloc_handle( current->process, server,
@@ -594,10 +613,12 @@ DECL_HANDLER(open_named_pipe)
         return;
     }
 
-    client = create_pipe_client( server );
+    client = create_pipe_client( server, req->flags );
     if( client )
     {
-        if( !socketpair( PF_UNIX, SOCK_STREAM, 0, fds ) )
+        if( !socketpair( PF_UNIX, SOCK_STREAM, 0, fds ) &&
+            (fcntl( fds[0], F_SETFL, O_NONBLOCK ) != -1) &&
+            (fcntl( fds[1], F_SETFL, O_NONBLOCK ) != -1))
         {
             assert( !client->fd );
             assert( !server->fd );
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.139
diff -u -p -r1.139 protocol.def
--- server/protocol.def 31 May 2005 13:37:16 -0000 1.139
+++ server/protocol.def 7 Jun 2005 21:00:06 -0000
@@ -1705,6 +1705,7 @@ enum message_type
 /* Open an existing named pipe */
 @REQ(open_named_pipe)
     unsigned int   access;
+    unsigned int   flags;        /* file flags */
     int            inherit;      /* inherit flag */
     VARARG(name,unicode_str);    /* pipe name */
 @REPLY
Index: server/trace.c
===================================================================
RCS file: /home/wine/wine/server/trace.c,v
retrieving revision 1.244
diff -u -p -r1.244 trace.c
--- server/trace.c 31 May 2005 13:37:16 -0000 1.244
+++ server/trace.c 7 Jun 2005 21:00:06 -0000
@@ -2145,6 +2145,7 @@ static void dump_create_named_pipe_reply
 static void dump_open_named_pipe_request( const struct open_named_pipe_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
+    fprintf( stderr, " flags=%08x,", req->flags );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " name=" );
     dump_varargs_unicode_str( cur_size );