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

View file

@ -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); */
};

View file

@ -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_pipe_ops =
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_server_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 */
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 object *obj, int verbose );
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_client_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 */
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 object *obj)
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 *fd, struct event **event )
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_server_obj( struct process *process,
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_server( struct named_pipe *pipe )
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_server( struct named_pipe *pipe )
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_client( struct pipe_server *server )
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 );

View file

@ -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

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