Implement overlapped I/O with named pipes.

This commit is contained in:
Robert Shearman 2005-06-08 19:11:46 +00:00 committed by Alexandre Julliard
parent 36a01505dc
commit e51dd36453
5 changed files with 49 additions and 24 deletions

View file

@ -158,6 +158,7 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
SERVER_START_REQ( open_named_pipe ) SERVER_START_REQ( open_named_pipe )
{ {
req->access = access; req->access = access;
req->flags = options;
req->inherit = (attr->Attributes & OBJ_INHERIT) != 0; req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
wine_server_add_data( req, attr->ObjectName->Buffer + 4, wine_server_add_data( req, attr->ObjectName->Buffer + 4,
attr->ObjectName->Length - 4*sizeof(WCHAR) ); attr->ObjectName->Length - 4*sizeof(WCHAR) );

View file

@ -2402,6 +2402,7 @@ struct open_named_pipe_request
{ {
struct request_header __header; struct request_header __header;
unsigned int access; unsigned int access;
unsigned int flags;
int inherit; int inherit;
/* VARARG(name,unicode_str); */ /* VARARG(name,unicode_str); */
}; };

View file

@ -44,6 +44,8 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "file.h" #include "file.h"
#include "handle.h" #include "handle.h"
@ -73,6 +75,7 @@ struct pipe_server
struct timeout_user *flush_poll; struct timeout_user *flush_poll;
struct event *event; struct event *event;
struct list wait_q; /* only a single one can be queued */ struct list wait_q; /* only a single one can be queued */
unsigned int options; /* pipe options */
}; };
struct pipe_client struct pipe_client
@ -80,6 +83,7 @@ struct pipe_client
struct object obj; /* object header */ struct object obj; /* object header */
struct fd *fd; /* pipe file descriptor */ struct fd *fd; /* pipe file descriptor */
struct pipe_server *server; /* server that this client is connected to */ struct pipe_server *server; /* server that this client is connected to */
unsigned int flags; /* file flags */
}; };
struct named_pipe struct named_pipe
@ -111,15 +115,12 @@ static const struct object_ops named_pipe_ops =
named_pipe_destroy /* destroy */ 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 */ /* server end functions */
static void pipe_server_dump( struct object *obj, int verbose ); static void pipe_server_dump( struct object *obj, int verbose );
static struct fd *pipe_server_get_fd( struct object *obj ); static struct fd *pipe_server_get_fd( struct object *obj );
static void pipe_server_destroy( 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_flush( struct fd *fd, struct event **event );
static int pipe_server_get_info( struct fd *fd );
static const struct object_ops pipe_server_ops = static const struct object_ops pipe_server_ops =
{ {
@ -136,12 +137,12 @@ static const struct object_ops pipe_server_ops =
static const struct fd_ops pipe_server_fd_ops = 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 */ default_poll_event, /* poll_event */
pipe_server_flush, /* flush */ pipe_server_flush, /* flush */
pipe_end_get_info, /* get_file_info */ pipe_server_get_info, /* get_file_info */
no_queue_async, /* queue_async */ default_fd_queue_async, /* queue_async */
no_cancel_async, /* cancel_async */ default_fd_cancel_async, /* cancel_async */
}; };
/* client end functions */ /* client end functions */
@ -149,6 +150,7 @@ static void pipe_client_dump( struct object *obj, int verbose );
static struct fd *pipe_client_get_fd( struct object *obj ); static struct fd *pipe_client_get_fd( struct object *obj );
static void pipe_client_destroy( 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_flush( struct fd *fd, struct event **event );
static int pipe_client_get_info( struct fd *fd );
static const struct object_ops pipe_client_ops = static const struct object_ops pipe_client_ops =
{ {
@ -165,12 +167,12 @@ static const struct object_ops pipe_client_ops =
static const struct fd_ops pipe_client_fd_ops = 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 */ default_poll_event, /* poll_event */
pipe_client_flush, /* flush */ pipe_client_flush, /* flush */
pipe_end_get_info, /* get_file_info */ pipe_client_get_info, /* get_file_info */
no_queue_async, /* queue_async */ default_fd_queue_async, /* queue_async */
no_cancel_async /* cancel_async */ default_fd_cancel_async /* cancel_async */
}; };
static void named_pipe_dump( struct object *obj, int verbose ) static void named_pipe_dump( struct object *obj, int verbose )
@ -330,11 +332,6 @@ static void pipe_client_destroy( struct object *obj)
assert( !client->fd ); 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 ) static int pipe_data_remaining( struct pipe_server *server )
{ {
struct pollfd pfd; struct pollfd pfd;
@ -417,9 +414,29 @@ static int pipe_client_flush( struct fd *fd, struct event **event )
return 0; 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 ) static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
@ -463,7 +480,7 @@ static struct pipe_server *get_pipe_server_obj( struct process *process,
return (struct pipe_server *) obj; 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; struct pipe_server *server;
@ -476,6 +493,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe )
server->state = ps_idle_server; server->state = ps_idle_server;
server->client = NULL; server->client = NULL;
server->flush_poll = NULL; server->flush_poll = NULL;
server->options = options;
list_init( &server->wait_q ); list_init( &server->wait_q );
list_add_head( &pipe->servers, &server->entry ); list_add_head( &pipe->servers, &server->entry );
@ -484,7 +502,7 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe )
return server; 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; struct pipe_client *client;
@ -494,6 +512,7 @@ static struct pipe_client *create_pipe_client( struct pipe_server *server )
client->fd = NULL; client->fd = NULL;
client->server = server; client->server = server;
client->flags = flags;
return client; 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) if(server)
{ {
reply->handle = alloc_handle( current->process, server, reply->handle = alloc_handle( current->process, server,
@ -594,10 +613,12 @@ DECL_HANDLER(open_named_pipe)
return; return;
} }
client = create_pipe_client( server ); client = create_pipe_client( server, req->flags );
if( client ) 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( !client->fd );
assert( !server->fd ); assert( !server->fd );

View file

@ -1705,6 +1705,7 @@ enum message_type
/* Open an existing named pipe */ /* Open an existing named pipe */
@REQ(open_named_pipe) @REQ(open_named_pipe)
unsigned int access; unsigned int access;
unsigned int flags; /* file flags */
int inherit; /* inherit flag */ int inherit; /* inherit flag */
VARARG(name,unicode_str); /* pipe name */ VARARG(name,unicode_str); /* pipe name */
@REPLY @REPLY

View file

@ -2145,6 +2145,7 @@ static void dump_create_named_pipe_reply( const struct create_named_pipe_reply *
static void dump_open_named_pipe_request( const struct open_named_pipe_request *req ) static void dump_open_named_pipe_request( const struct open_named_pipe_request *req )
{ {
fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " flags=%08x,", req->flags );
fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " name=" ); fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size ); dump_varargs_unicode_str( cur_size );