mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 01:14:47 +00:00
server: Introduced new pipe_end struct containing common parts of pipe_client and pipe_server.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a3acdf117f
commit
8989867544
|
@ -65,10 +65,16 @@ enum pipe_state
|
||||||
|
|
||||||
struct named_pipe;
|
struct named_pipe;
|
||||||
|
|
||||||
struct pipe_server
|
struct pipe_end
|
||||||
{
|
{
|
||||||
struct object obj; /* object header */
|
struct object obj; /* object header */
|
||||||
struct fd *fd; /* pipe file descriptor */
|
struct fd *fd; /* pipe file descriptor */
|
||||||
|
unsigned int flags; /* pipe flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pipe_server
|
||||||
|
{
|
||||||
|
struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */
|
||||||
struct fd *ioctl_fd; /* file descriptor for ioctls when not connected */
|
struct fd *ioctl_fd; /* file descriptor for ioctls when not connected */
|
||||||
struct list entry; /* entry in named pipe servers list */
|
struct list entry; /* entry in named pipe servers list */
|
||||||
enum pipe_state state; /* server state */
|
enum pipe_state state; /* server state */
|
||||||
|
@ -76,16 +82,13 @@ struct pipe_server
|
||||||
struct named_pipe *pipe;
|
struct named_pipe *pipe;
|
||||||
struct timeout_user *flush_poll;
|
struct timeout_user *flush_poll;
|
||||||
unsigned int options; /* pipe options */
|
unsigned int options; /* pipe options */
|
||||||
unsigned int pipe_flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipe_client
|
struct pipe_client
|
||||||
{
|
{
|
||||||
struct object obj; /* object header */
|
struct pipe_end pipe_end; /* common header for pipe_client and pipe_server */
|
||||||
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 */
|
unsigned int flags; /* file flags */
|
||||||
unsigned int pipe_flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct named_pipe
|
struct named_pipe
|
||||||
|
@ -304,7 +307,7 @@ static int pipe_client_signaled( struct object *obj, struct wait_queue_entry *en
|
||||||
{
|
{
|
||||||
struct pipe_client *client = (struct pipe_client *) obj;
|
struct pipe_client *client = (struct pipe_client *) obj;
|
||||||
|
|
||||||
return client->fd && is_fd_signaled(client->fd);
|
return client->pipe_end.fd && is_fd_signaled(client->pipe_end.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void named_pipe_destroy( struct object *obj)
|
static void named_pipe_destroy( struct object *obj)
|
||||||
|
@ -319,8 +322,8 @@ static void named_pipe_destroy( struct object *obj)
|
||||||
static struct fd *pipe_client_get_fd( struct object *obj )
|
static struct fd *pipe_client_get_fd( struct object *obj )
|
||||||
{
|
{
|
||||||
struct pipe_client *client = (struct pipe_client *) obj;
|
struct pipe_client *client = (struct pipe_client *) obj;
|
||||||
if (client->fd)
|
if (client->pipe_end.fd)
|
||||||
return (struct fd *) grab_object( client->fd );
|
return (struct fd *) grab_object( client->pipe_end.fd );
|
||||||
set_error( STATUS_PIPE_DISCONNECTED );
|
set_error( STATUS_PIPE_DISCONNECTED );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -333,15 +336,15 @@ static void set_server_state( struct pipe_server *server, enum pipe_state state
|
||||||
{
|
{
|
||||||
case ps_connected_server:
|
case ps_connected_server:
|
||||||
case ps_wait_disconnect:
|
case ps_wait_disconnect:
|
||||||
assert( server->fd );
|
assert( server->pipe_end.fd );
|
||||||
break;
|
break;
|
||||||
case ps_wait_open:
|
case ps_wait_open:
|
||||||
case ps_idle_server:
|
case ps_idle_server:
|
||||||
assert( !server->fd );
|
assert( !server->pipe_end.fd );
|
||||||
set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING );
|
set_no_fd_status( server->ioctl_fd, STATUS_PIPE_LISTENING );
|
||||||
break;
|
break;
|
||||||
case ps_wait_connect:
|
case ps_wait_connect:
|
||||||
assert( !server->fd );
|
assert( !server->pipe_end.fd );
|
||||||
set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED );
|
set_no_fd_status( server->ioctl_fd, STATUS_PIPE_DISCONNECTED );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +354,7 @@ static struct fd *pipe_server_get_fd( struct object *obj )
|
||||||
{
|
{
|
||||||
struct pipe_server *server = (struct pipe_server *) obj;
|
struct pipe_server *server = (struct pipe_server *) obj;
|
||||||
|
|
||||||
return (struct fd *)grab_object( server->fd ? server->fd : server->ioctl_fd );
|
return (struct fd *)grab_object( server->pipe_end.fd ? server->pipe_end.fd : server->ioctl_fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -362,7 +365,7 @@ static void notify_empty( struct pipe_server *server )
|
||||||
assert( server->state == ps_connected_server );
|
assert( server->state == ps_connected_server );
|
||||||
remove_timeout_user( server->flush_poll );
|
remove_timeout_user( server->flush_poll );
|
||||||
server->flush_poll = NULL;
|
server->flush_poll = NULL;
|
||||||
fd_async_wake_up( server->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_disconnect( struct pipe_server *server )
|
static void do_disconnect( struct pipe_server *server )
|
||||||
|
@ -371,14 +374,14 @@ static void do_disconnect( struct pipe_server *server )
|
||||||
if (server->client)
|
if (server->client)
|
||||||
{
|
{
|
||||||
assert( server->client->server == server );
|
assert( server->client->server == server );
|
||||||
assert( server->client->fd );
|
assert( server->client->pipe_end.fd );
|
||||||
release_object( server->client->fd );
|
release_object( server->client->pipe_end.fd );
|
||||||
server->client->fd = NULL;
|
server->client->pipe_end.fd = NULL;
|
||||||
}
|
}
|
||||||
assert( server->fd );
|
assert( server->pipe_end.fd );
|
||||||
shutdown( get_unix_fd( server->fd ), SHUT_RDWR );
|
shutdown( get_unix_fd( server->pipe_end.fd ), SHUT_RDWR );
|
||||||
release_object( server->fd );
|
release_object( server->pipe_end.fd );
|
||||||
server->fd = NULL;
|
server->pipe_end.fd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pipe_server_destroy( struct object *obj)
|
static void pipe_server_destroy( struct object *obj)
|
||||||
|
@ -387,7 +390,7 @@ static void pipe_server_destroy( struct object *obj)
|
||||||
|
|
||||||
assert( obj->ops == &pipe_server_ops );
|
assert( obj->ops == &pipe_server_ops );
|
||||||
|
|
||||||
if (server->fd)
|
if (server->pipe_end.fd)
|
||||||
{
|
{
|
||||||
notify_empty( server );
|
notify_empty( server );
|
||||||
do_disconnect( server );
|
do_disconnect( server );
|
||||||
|
@ -435,7 +438,7 @@ static void pipe_client_destroy( struct object *obj)
|
||||||
server->client = NULL;
|
server->client = NULL;
|
||||||
client->server = NULL;
|
client->server = NULL;
|
||||||
}
|
}
|
||||||
if (client->fd) release_object( client->fd );
|
if (client->pipe_end.fd) release_object( client->pipe_end.fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void named_pipe_device_dump( struct object *obj, int verbose )
|
static void named_pipe_device_dump( struct object *obj, int verbose )
|
||||||
|
@ -517,7 +520,7 @@ static int pipe_data_remaining( struct pipe_server *server )
|
||||||
|
|
||||||
assert( server->client );
|
assert( server->client );
|
||||||
|
|
||||||
fd = get_unix_fd( server->client->fd );
|
fd = get_unix_fd( server->client->pipe_end.fd );
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
pfd.fd = fd;
|
pfd.fd = fd;
|
||||||
|
@ -541,7 +544,7 @@ static void check_flushed( void *arg )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server->flush_poll = NULL;
|
server->flush_poll = NULL;
|
||||||
fd_async_wake_up( server->fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
fd_async_wake_up( server->pipe_end.fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +557,7 @@ static obj_handle_t pipe_server_flush( struct fd *fd, struct async *async, int b
|
||||||
|
|
||||||
if (!pipe_data_remaining( server )) return 0;
|
if (!pipe_data_remaining( server )) return 0;
|
||||||
|
|
||||||
if (fd_queue_async( server->fd, async, ASYNC_TYPE_WAIT ))
|
if (fd_queue_async( server->pipe_end.fd, async, ASYNC_TYPE_WAIT ))
|
||||||
{
|
{
|
||||||
/* there's no unix way to be alerted when a pipe becomes empty, so resort to polling */
|
/* there's no unix way to be alerted when a pipe becomes empty, so resort to polling */
|
||||||
if (!server->flush_poll)
|
if (!server->flush_poll)
|
||||||
|
@ -625,7 +628,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct
|
||||||
{
|
{
|
||||||
case ps_connected_server:
|
case ps_connected_server:
|
||||||
assert( server->client );
|
assert( server->client );
|
||||||
assert( server->client->fd );
|
assert( server->client->pipe_end.fd );
|
||||||
|
|
||||||
notify_empty( server );
|
notify_empty( server );
|
||||||
|
|
||||||
|
@ -663,6 +666,12 @@ static struct pipe_server *get_pipe_server_obj( struct process *process,
|
||||||
return (struct pipe_server *) obj;
|
return (struct pipe_server *) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_pipe_end( struct pipe_end *pipe_end, unsigned int pipe_flags )
|
||||||
|
{
|
||||||
|
pipe_end->fd = NULL;
|
||||||
|
pipe_end->flags = pipe_flags;
|
||||||
|
}
|
||||||
|
|
||||||
static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options,
|
static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned int options,
|
||||||
unsigned int pipe_flags )
|
unsigned int pipe_flags )
|
||||||
{
|
{
|
||||||
|
@ -672,16 +681,15 @@ static struct pipe_server *create_pipe_server( struct named_pipe *pipe, unsigned
|
||||||
if (!server)
|
if (!server)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
server->fd = NULL;
|
|
||||||
server->pipe = pipe;
|
server->pipe = pipe;
|
||||||
server->client = NULL;
|
server->client = NULL;
|
||||||
server->flush_poll = NULL;
|
server->flush_poll = NULL;
|
||||||
server->options = options;
|
server->options = options;
|
||||||
server->pipe_flags = pipe_flags;
|
init_pipe_end( &server->pipe_end, pipe_flags );
|
||||||
|
|
||||||
list_add_head( &pipe->servers, &server->entry );
|
list_add_head( &pipe->servers, &server->entry );
|
||||||
grab_object( pipe );
|
grab_object( pipe );
|
||||||
if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->obj, options )))
|
if (!(server->ioctl_fd = alloc_pseudo_fd( &pipe_server_fd_ops, &server->pipe_end.obj, options )))
|
||||||
{
|
{
|
||||||
release_object( server );
|
release_object( server );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -699,10 +707,9 @@ static struct pipe_client *create_pipe_client( unsigned int flags, unsigned int
|
||||||
if (!client)
|
if (!client)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
client->fd = NULL;
|
|
||||||
client->server = NULL;
|
client->server = NULL;
|
||||||
client->flags = flags;
|
client->flags = flags;
|
||||||
client->pipe_flags = pipe_flags;
|
init_pipe_end( &client->pipe_end, pipe_flags );
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -770,7 +777,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
||||||
{
|
{
|
||||||
if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
|
if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
|
||||||
{
|
{
|
||||||
assert( !server->fd );
|
assert( !server->pipe_end.fd );
|
||||||
|
|
||||||
/* for performance reasons, only set nonblocking mode when using
|
/* for performance reasons, only set nonblocking mode when using
|
||||||
* overlapped I/O. Otherwise, we will be doing too much busy
|
* overlapped I/O. Otherwise, we will be doing too much busy
|
||||||
|
@ -789,13 +796,13 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
||||||
setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
||||||
}
|
}
|
||||||
|
|
||||||
client->fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->obj, options );
|
client->pipe_end.fd = create_anonymous_fd( &pipe_client_fd_ops, fds[1], &client->pipe_end.obj, options );
|
||||||
server->fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->obj, server->options );
|
server->pipe_end.fd = create_anonymous_fd( &pipe_server_fd_ops, fds[0], &server->pipe_end.obj, server->options );
|
||||||
if (client->fd && server->fd)
|
if (client->pipe_end.fd && server->pipe_end.fd)
|
||||||
{
|
{
|
||||||
allow_fd_caching( client->fd );
|
allow_fd_caching( client->pipe_end.fd );
|
||||||
allow_fd_caching( server->fd );
|
allow_fd_caching( server->pipe_end.fd );
|
||||||
fd_copy_completion( server->ioctl_fd, server->fd );
|
fd_copy_completion( server->ioctl_fd, server->pipe_end.fd );
|
||||||
if (server->state == ps_wait_open)
|
if (server->state == ps_wait_open)
|
||||||
fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
fd_async_wake_up( server->ioctl_fd, ASYNC_TYPE_WAIT, STATUS_SUCCESS );
|
||||||
set_server_state( server, ps_connected_server );
|
set_server_state( server, ps_connected_server );
|
||||||
|
@ -816,7 +823,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
release_object( server );
|
release_object( server );
|
||||||
return &client->obj;
|
return &client->pipe_end.obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
|
static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code,
|
||||||
|
@ -938,10 +945,10 @@ DECL_HANDLER(create_named_pipe)
|
||||||
{
|
{
|
||||||
reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes );
|
reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes );
|
||||||
server->pipe->instances++;
|
server->pipe->instances++;
|
||||||
if (sd) default_set_sd( &server->obj, sd, OWNER_SECURITY_INFORMATION |
|
if (sd) default_set_sd( &server->pipe_end.obj, sd, OWNER_SECURITY_INFORMATION |
|
||||||
GROUP_SECURITY_INFORMATION |
|
GROUP_SECURITY_INFORMATION |
|
||||||
DACL_SECURITY_INFORMATION |
|
DACL_SECURITY_INFORMATION |
|
||||||
SACL_SECURITY_INFORMATION );
|
SACL_SECURITY_INFORMATION );
|
||||||
release_object( server );
|
release_object( server );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,7 +973,7 @@ DECL_HANDLER(get_named_pipe_info)
|
||||||
server = client->server;
|
server = client->server;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply->flags = client ? client->pipe_flags : server->pipe_flags;
|
reply->flags = client ? client->pipe_end.flags : server->pipe_end.flags;
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
reply->sharing = server->pipe->sharing;
|
reply->sharing = server->pipe->sharing;
|
||||||
|
@ -1014,11 +1021,11 @@ DECL_HANDLER(set_named_pipe_info)
|
||||||
}
|
}
|
||||||
else if (client)
|
else if (client)
|
||||||
{
|
{
|
||||||
client->pipe_flags = server->pipe->flags | req->flags;
|
client->pipe_end.flags = server->pipe->flags | req->flags;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server->pipe_flags = server->pipe->flags | req->flags;
|
server->pipe_end.flags = server->pipe->flags | req->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
|
|
Loading…
Reference in a new issue