mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 01:49:16 +00:00
Implement overlapped I/O with named pipes.
This commit is contained in:
parent
36a01505dc
commit
e51dd36453
|
@ -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) );
|
||||||
|
|
|
@ -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); */
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in a new issue