server: Make async_queue object a simple list instead of a server object.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-07-04 15:26:19 +02:00 committed by Alexandre Julliard
parent 7f17bae74e
commit 0b4c8bf93f
5 changed files with 83 additions and 149 deletions

View File

@ -82,40 +82,6 @@ static const struct object_ops async_ops =
async_destroy /* destroy */ async_destroy /* destroy */
}; };
struct async_queue
{
struct object obj; /* object header */
struct fd *fd; /* file descriptor owning this queue */
struct list queue; /* queue of async objects */
};
static void async_queue_dump( struct object *obj, int verbose );
static void async_queue_destroy( struct object *obj );
static const struct object_ops async_queue_ops =
{
sizeof(struct async_queue), /* size */
async_queue_dump, /* dump */
no_get_type, /* get_type */
no_add_queue, /* add_queue */
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
no_map_access, /* map_access */
default_get_sd, /* get_sd */
default_set_sd, /* set_sd */
no_lookup_name, /* lookup_name */
no_link_name, /* link_name */
NULL, /* unlink_name */
no_open_file, /* open_file */
no_close_handle, /* close_handle */
async_queue_destroy /* destroy */
};
static inline void async_reselect( struct async *async ) static inline void async_reselect( struct async *async )
{ {
if (async->queue && async->fd) fd_reselect_async( async->fd, async->queue ); if (async->queue && async->fd) fd_reselect_async( async->fd, async->queue );
@ -165,7 +131,6 @@ static void async_destroy( struct object *obj )
{ {
list_remove( &async->queue_entry ); list_remove( &async->queue_entry );
async_reselect( async ); async_reselect( async );
release_object( async->queue );
} }
else if (async->fd) release_object( async->fd ); else if (async->fd) release_object( async->fd );
@ -176,18 +141,6 @@ static void async_destroy( struct object *obj )
release_object( async->thread ); release_object( async->thread );
} }
static void async_queue_dump( struct object *obj, int verbose )
{
struct async_queue *async_queue = (struct async_queue *)obj;
assert( obj->ops == &async_queue_ops );
fprintf( stderr, "Async queue fd=%p\n", async_queue->fd );
}
static void async_queue_destroy( struct object *obj )
{
assert( obj->ops == &async_queue_ops );
}
/* notifies client thread of new status of its async request */ /* notifies client thread of new status of its async request */
void async_terminate( struct async *async, unsigned int status ) void async_terminate( struct async *async, unsigned int status )
{ {
@ -232,33 +185,18 @@ static void async_timeout( void *private )
async_terminate( async, async->timeout_status ); async_terminate( async, async->timeout_status );
} }
/* create a new async queue for a given fd */
struct async_queue *create_async_queue( struct fd *fd )
{
struct async_queue *queue = alloc_object( &async_queue_ops );
if (queue)
{
queue->fd = fd;
list_init( &queue->queue );
}
return queue;
}
/* free an async queue, cancelling all async operations */ /* free an async queue, cancelling all async operations */
void free_async_queue( struct async_queue *queue ) void free_async_queue( struct async_queue *queue )
{ {
struct async *async; struct async *async, *next;
if (!queue) return; LIST_FOR_EACH_ENTRY_SAFE( async, next, &queue->queue, struct async, queue_entry )
LIST_FOR_EACH_ENTRY( async, &queue->queue, struct async, queue_entry )
{ {
async->completion = fd_get_completion( async->fd, &async->comp_key ); async->completion = fd_get_completion( async->fd, &async->comp_key );
async->fd = NULL; async->fd = NULL;
async_terminate( async, STATUS_HANDLES_CLOSED );
async->queue = NULL;
} }
queue->fd = NULL;
async_wake_up( queue, STATUS_HANDLES_CLOSED );
release_object( queue );
} }
void queue_async( struct async_queue *queue, struct async *async ) void queue_async( struct async_queue *queue, struct async *async )
@ -266,7 +204,7 @@ void queue_async( struct async_queue *queue, struct async *async )
/* fd will be set to NULL in free_async_queue when fd is destroyed */ /* fd will be set to NULL in free_async_queue when fd is destroyed */
release_object( async->fd ); release_object( async->fd );
async->queue = (struct async_queue *)grab_object( queue ); async->queue = queue;
grab_object( async ); grab_object( async );
list_add_tail( &queue->queue, &async->queue_entry ); list_add_tail( &queue->queue, &async->queue_entry );

View File

@ -189,9 +189,9 @@ struct fd
unsigned int signaled :1; /* is the fd signaled? */ unsigned int signaled :1; /* is the fd signaled? */
unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */ unsigned int fs_locks :1; /* can we use filesystem locks for this fd? */
int poll_index; /* index of fd in poll array */ int poll_index; /* index of fd in poll array */
struct async_queue *read_q; /* async readers of this fd */ struct async_queue read_q; /* async readers of this fd */
struct async_queue *write_q; /* async writers of this fd */ struct async_queue write_q; /* async writers of this fd */
struct async_queue *wait_q; /* other async waiters of this fd */ struct async_queue wait_q; /* other async waiters of this fd */
struct completion *completion; /* completion object attached to this fd */ struct completion *completion; /* completion object attached to this fd */
apc_param_t comp_key; /* completion key to set in completion events */ apc_param_t comp_key; /* completion key to set in completion events */
}; };
@ -1473,9 +1473,9 @@ static void fd_destroy( struct object *obj )
{ {
struct fd *fd = (struct fd *)obj; struct fd *fd = (struct fd *)obj;
free_async_queue( fd->read_q ); free_async_queue( &fd->read_q );
free_async_queue( fd->write_q ); free_async_queue( &fd->write_q );
free_async_queue( fd->wait_q ); free_async_queue( &fd->wait_q );
if (fd->completion) release_object( fd->completion ); if (fd->completion) release_object( fd->completion );
remove_fd_locks( fd ); remove_fd_locks( fd );
@ -1567,8 +1567,8 @@ static inline void unmount_fd( struct fd *fd )
{ {
assert( fd->inode ); assert( fd->inode );
async_wake_up( fd->read_q, STATUS_VOLUME_DISMOUNTED ); async_wake_up( &fd->read_q, STATUS_VOLUME_DISMOUNTED );
async_wake_up( fd->write_q, STATUS_VOLUME_DISMOUNTED ); async_wake_up( &fd->write_q, STATUS_VOLUME_DISMOUNTED );
if (fd->poll_index != -1) set_fd_events( fd, -1 ); if (fd->poll_index != -1) set_fd_events( fd, -1 );
@ -1603,10 +1603,10 @@ static struct fd *alloc_fd_object(void)
fd->signaled = 1; fd->signaled = 1;
fd->fs_locks = 1; fd->fs_locks = 1;
fd->poll_index = -1; fd->poll_index = -1;
fd->read_q = NULL;
fd->write_q = NULL;
fd->wait_q = NULL;
fd->completion = NULL; fd->completion = NULL;
init_async_queue( &fd->read_q );
init_async_queue( &fd->write_q );
init_async_queue( &fd->wait_q );
list_init( &fd->inode_entry ); list_init( &fd->inode_entry );
list_init( &fd->locks ); list_init( &fd->locks );
@ -1638,11 +1638,11 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd->signaled = 0; fd->signaled = 0;
fd->fs_locks = 0; fd->fs_locks = 0;
fd->poll_index = -1; fd->poll_index = -1;
fd->read_q = NULL;
fd->write_q = NULL;
fd->wait_q = NULL;
fd->completion = NULL; fd->completion = NULL;
fd->no_fd_status = STATUS_BAD_DEVICE_TYPE; fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
init_async_queue( &fd->read_q );
init_async_queue( &fd->write_q );
init_async_queue( &fd->wait_q );
list_init( &fd->inode_entry ); list_init( &fd->inode_entry );
list_init( &fd->locks ); list_init( &fd->locks );
return fd; return fd;
@ -2014,16 +2014,16 @@ int default_fd_get_poll_events( struct fd *fd )
{ {
int events = 0; int events = 0;
if (async_waiting( fd->read_q )) events |= POLLIN; if (async_waiting( &fd->read_q )) events |= POLLIN;
if (async_waiting( fd->write_q )) events |= POLLOUT; if (async_waiting( &fd->write_q )) events |= POLLOUT;
return events; return events;
} }
/* default handler for poll() events */ /* default handler for poll() events */
void default_poll_event( struct fd *fd, int event ) void default_poll_event( struct fd *fd, int event )
{ {
if (event & (POLLIN | POLLERR | POLLHUP)) async_wake_up( fd->read_q, STATUS_ALERTED ); if (event & (POLLIN | POLLERR | POLLHUP)) async_wake_up( &fd->read_q, STATUS_ALERTED );
if (event & (POLLOUT | POLLERR | POLLHUP)) async_wake_up( fd->write_q, STATUS_ALERTED ); if (event & (POLLOUT | POLLERR | POLLHUP)) async_wake_up( &fd->write_q, STATUS_ALERTED );
/* if an error occurred, stop polling this fd to avoid busy-looping */ /* if an error occurred, stop polling this fd to avoid busy-looping */
if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 ); if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 );
@ -2037,16 +2037,13 @@ int fd_queue_async( struct fd *fd, struct async *async, int type )
switch (type) switch (type)
{ {
case ASYNC_TYPE_READ: case ASYNC_TYPE_READ:
if (!fd->read_q && !(fd->read_q = create_async_queue( fd ))) return 0; queue = &fd->read_q;
queue = fd->read_q;
break; break;
case ASYNC_TYPE_WRITE: case ASYNC_TYPE_WRITE:
if (!fd->write_q && !(fd->write_q = create_async_queue( fd ))) return 0; queue = &fd->write_q;
queue = fd->write_q;
break; break;
case ASYNC_TYPE_WAIT: case ASYNC_TYPE_WAIT:
if (!fd->wait_q && !(fd->wait_q = create_async_queue( fd ))) return 0; queue = &fd->wait_q;
queue = fd->wait_q;
break; break;
default: default:
queue = NULL; queue = NULL;
@ -2070,13 +2067,13 @@ void fd_async_wake_up( struct fd *fd, int type, unsigned int status )
switch (type) switch (type)
{ {
case ASYNC_TYPE_READ: case ASYNC_TYPE_READ:
async_wake_up( fd->read_q, status ); async_wake_up( &fd->read_q, status );
break; break;
case ASYNC_TYPE_WRITE: case ASYNC_TYPE_WRITE:
async_wake_up( fd->write_q, status ); async_wake_up( &fd->write_q, status );
break; break;
case ASYNC_TYPE_WAIT: case ASYNC_TYPE_WAIT:
async_wake_up( fd->wait_q, status ); async_wake_up( &fd->wait_q, status );
break; break;
default: default:
assert(0); assert(0);
@ -2101,7 +2098,7 @@ void default_fd_queue_async( struct fd *fd, struct async *async, int type, int c
/* default reselect_async() fd routine */ /* default reselect_async() fd routine */
void default_fd_reselect_async( struct fd *fd, struct async_queue *queue ) void default_fd_reselect_async( struct fd *fd, struct async_queue *queue )
{ {
if (queue == fd->read_q || queue == fd->write_q) if (queue == &fd->read_q || queue == &fd->write_q)
{ {
int poll_events = fd->fd_ops->get_poll_events( fd ); int poll_events = fd->fd_ops->get_poll_events( fd );
int events = check_fd_events( fd, poll_events ); int events = check_fd_events( fd, poll_events );

View File

@ -42,6 +42,11 @@ struct iosb
void *out_data; /* output data */ void *out_data; /* output data */
}; };
struct async_queue
{
struct list queue; /* queue of async objects */
};
/* operations valid on file descriptor objects */ /* operations valid on file descriptor objects */
struct fd_ops struct fd_ops
{ {
@ -173,7 +178,6 @@ extern int is_serial_fd( struct fd *fd );
extern struct object *create_serial( struct fd *fd ); extern struct object *create_serial( struct fd *fd );
/* async I/O functions */ /* async I/O functions */
extern struct async_queue *create_async_queue( struct fd *fd );
extern void free_async_queue( struct async_queue *queue ); extern void free_async_queue( struct async_queue *queue );
extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb ); extern struct async *create_async( struct fd *fd, struct thread *thread, const async_data_t *data, struct iosb *iosb );
extern struct async *create_request_async( struct fd *fd, const async_data_t *data ); extern struct async *create_request_async( struct fd *fd, const async_data_t *data );
@ -193,6 +197,11 @@ extern int async_is_blocking( struct async *async );
extern struct async *find_pending_async( struct async_queue *queue ); extern struct async *find_pending_async( struct async_queue *queue );
extern void cancel_process_asyncs( struct process *process ); extern void cancel_process_asyncs( struct process *process );
static inline void init_async_queue( struct async_queue *queue )
{
list_init( &queue->queue );
}
/* access rights that require Unix read permission */ /* access rights that require Unix read permission */
#define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) #define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)

View File

@ -79,8 +79,8 @@ struct pipe_end
struct pipe_end *connection; /* the other end of the pipe */ struct pipe_end *connection; /* the other end of the pipe */
data_size_t buffer_size;/* size of buffered data that doesn't block caller */ data_size_t buffer_size;/* size of buffered data that doesn't block caller */
struct list message_queue; struct list message_queue;
struct async_queue *read_q; /* read queue */ struct async_queue read_q; /* read queue */
struct async_queue *write_q; /* write queue */ struct async_queue write_q; /* write queue */
}; };
struct pipe_server struct pipe_server
@ -113,7 +113,7 @@ struct named_pipe
unsigned int instances; unsigned int instances;
timeout_t timeout; timeout_t timeout;
struct list servers; /* list of servers using this pipe */ struct list servers; /* list of servers using this pipe */
struct async_queue *waiters; /* list of clients waiting to connect */ struct async_queue waiters; /* list of clients waiting to connect */
}; };
struct named_pipe_device struct named_pipe_device
@ -337,7 +337,7 @@ static void named_pipe_destroy( struct object *obj)
assert( list_empty( &pipe->servers ) ); assert( list_empty( &pipe->servers ) );
assert( !pipe->instances ); assert( !pipe->instances );
free_async_queue( pipe->waiters ); free_async_queue( &pipe->waiters );
} }
static struct fd *pipe_client_get_fd( struct object *obj ) static struct fd *pipe_client_get_fd( struct object *obj )
@ -421,7 +421,7 @@ static void pipe_end_disconnect( struct pipe_end *pipe_end, unsigned int status
struct pipe_message *message, *next; struct pipe_message *message, *next;
struct async *async; struct async *async;
if (pipe_end->fd) fd_async_wake_up( pipe_end->fd, ASYNC_TYPE_WAIT, status ); if (pipe_end->fd) fd_async_wake_up( pipe_end->fd, ASYNC_TYPE_WAIT, status );
async_wake_up( pipe_end->read_q, status ); async_wake_up( &pipe_end->read_q, status );
LIST_FOR_EACH_ENTRY_SAFE( message, next, &pipe_end->message_queue, struct pipe_message, entry ) LIST_FOR_EACH_ENTRY_SAFE( message, next, &pipe_end->message_queue, struct pipe_message, entry )
{ {
async = message->async; async = message->async;
@ -470,8 +470,8 @@ static void pipe_end_destroy( struct pipe_end *pipe_end )
free_message( message ); free_message( message );
} }
free_async_queue( pipe_end->read_q ); free_async_queue( &pipe_end->read_q );
free_async_queue( pipe_end->write_q ); free_async_queue( &pipe_end->write_q );
} }
static void pipe_server_destroy( struct object *obj) static void pipe_server_destroy( struct object *obj)
@ -756,7 +756,7 @@ static void reselect_read_queue( struct pipe_end *pipe_end )
int read_done = 0; int read_done = 0;
ignore_reselect = 1; ignore_reselect = 1;
while (!list_empty( &pipe_end->message_queue) && (async = find_pending_async( pipe_end->read_q ))) while (!list_empty( &pipe_end->message_queue ) && (async = find_pending_async( &pipe_end->read_q )))
{ {
iosb = async_get_iosb( async ); iosb = async_get_iosb( async );
message_queue_read( pipe_end, iosb ); message_queue_read( pipe_end, iosb );
@ -818,9 +818,7 @@ static int pipe_end_read( struct fd *fd, struct async *async, file_pos_t pos )
return 0; return 0;
} }
if (!pipe_end->read_q && !(pipe_end->read_q = create_async_queue( fd ))) return 0; queue_async( &pipe_end->read_q, async );
queue_async( pipe_end->read_q, async );
reselect_read_queue( pipe_end ); reselect_read_queue( pipe_end );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
return 1; return 1;
@ -840,15 +838,13 @@ static int pipe_end_write( struct fd *fd, struct async *async, file_pos_t pos )
return 0; return 0;
} }
if (!write_end->write_q && !(write_end->write_q = create_async_queue( fd ))) return 0;
if (!(message = mem_alloc( sizeof(*message) ))) return 0; if (!(message = mem_alloc( sizeof(*message) ))) return 0;
message->async = (struct async *)grab_object( async ); message->async = (struct async *)grab_object( async );
message->iosb = async_get_iosb( async ); message->iosb = async_get_iosb( async );
message->read_pos = 0; message->read_pos = 0;
list_add_tail( &read_end->message_queue, &message->entry ); list_add_tail( &read_end->message_queue, &message->entry );
queue_async( write_end->write_q, async ); queue_async( &write_end->write_q, async );
reselect_write_queue( write_end ); reselect_write_queue( write_end );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
return 1; return 1;
@ -869,9 +865,9 @@ static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue )
if (!use_server_io( pipe_end )) if (!use_server_io( pipe_end ))
default_fd_reselect_async( fd, queue ); default_fd_reselect_async( fd, queue );
else if (pipe_end->write_q && pipe_end->write_q == queue) else if (&pipe_end->write_q == queue)
reselect_write_queue( pipe_end ); reselect_write_queue( pipe_end );
else if (pipe_end->read_q && pipe_end->read_q == queue) else if (&pipe_end->read_q == queue)
reselect_read_queue( pipe_end ); reselect_read_queue( pipe_end );
} }
@ -940,7 +936,7 @@ static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *as
if (fd_queue_async( server->ioctl_fd, async, ASYNC_TYPE_WAIT )) if (fd_queue_async( server->ioctl_fd, async, ASYNC_TYPE_WAIT ))
{ {
set_server_state( server, ps_wait_open ); set_server_state( server, ps_wait_open );
if (server->pipe->waiters) async_wake_up( server->pipe->waiters, STATUS_SUCCESS ); async_wake_up( &server->pipe->waiters, STATUS_SUCCESS );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
return 1; return 1;
} }
@ -1025,8 +1021,8 @@ static void init_pipe_end( struct pipe_end *pipe_end, unsigned int pipe_flags, d
pipe_end->flags = pipe_flags; pipe_end->flags = pipe_flags;
pipe_end->connection = NULL; pipe_end->connection = NULL;
pipe_end->buffer_size = buffer_size; pipe_end->buffer_size = buffer_size;
pipe_end->read_q = NULL; init_async_queue( &pipe_end->read_q );
pipe_end->write_q = NULL; init_async_queue( &pipe_end->write_q );
list_init( &pipe_end->message_queue ); list_init( &pipe_end->message_queue );
} }
@ -1231,18 +1227,15 @@ static int named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, struct asy
if (!(server = find_available_server( pipe ))) if (!(server = find_available_server( pipe )))
{ {
if (!pipe->waiters && !(pipe->waiters = create_async_queue( fd ))) goto done; queue_async( &pipe->waiters, async );
queue_async( pipe->waiters, async );
when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout; when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
async_set_timeout( async, when, STATUS_IO_TIMEOUT ); async_set_timeout( async, when, STATUS_IO_TIMEOUT );
release_object( pipe ); release_object( pipe );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
return 1; return 1;
} }
else release_object( server );
done: release_object( server );
release_object( pipe ); release_object( pipe );
return 0; return 0;
} }
@ -1291,7 +1284,7 @@ DECL_HANDLER(create_named_pipe)
{ {
/* initialize it if it didn't already exist */ /* initialize it if it didn't already exist */
pipe->instances = 0; pipe->instances = 0;
pipe->waiters = NULL; init_async_queue( &pipe->waiters );
list_init( &pipe->servers ); list_init( &pipe->servers );
pipe->insize = req->insize; pipe->insize = req->insize;
pipe->outsize = req->outsize; pipe->outsize = req->outsize;

View File

@ -112,9 +112,9 @@ struct sock
int errors[FD_MAX_EVENTS]; /* event errors */ int errors[FD_MAX_EVENTS]; /* event errors */
timeout_t connect_time;/* time the socket was connected */ timeout_t connect_time;/* time the socket was connected */
struct sock *deferred; /* socket that waits for a deferred accept */ struct sock *deferred; /* socket that waits for a deferred accept */
struct async_queue *read_q; /* queue for asynchronous reads */ struct async_queue read_q; /* queue for asynchronous reads */
struct async_queue *write_q; /* queue for asynchronous writes */ struct async_queue write_q; /* queue for asynchronous writes */
struct async_queue *ifchange_q; /* queue for interface change notifications */ struct async_queue ifchange_q; /* queue for interface change notifications */
struct object *ifchange_obj; /* the interface change notification object */ struct object *ifchange_obj; /* the interface change notification object */
struct list ifchange_entry; /* entry in ifchange notification list */ struct list ifchange_entry; /* entry in ifchange notification list */
}; };
@ -312,16 +312,16 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
{ {
if ( sock->flags & WSA_FLAG_OVERLAPPED ) if ( sock->flags & WSA_FLAG_OVERLAPPED )
{ {
if ( event & (POLLIN|POLLPRI) && async_waiting( sock->read_q ) ) if (event & (POLLIN|POLLPRI) && async_waiting( &sock->read_q ))
{ {
if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock ); if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock );
async_wake_up( sock->read_q, STATUS_ALERTED ); async_wake_up( &sock->read_q, STATUS_ALERTED );
event &= ~(POLLIN|POLLPRI); event &= ~(POLLIN|POLLPRI);
} }
if ( event & POLLOUT && async_waiting( sock->write_q ) ) if (event & POLLOUT && async_waiting( &sock->write_q ))
{ {
if (debug_level) fprintf( stderr, "activating write queue for socket %p\n", sock ); if (debug_level) fprintf( stderr, "activating write queue for socket %p\n", sock );
async_wake_up( sock->write_q, STATUS_ALERTED ); async_wake_up( &sock->write_q, STATUS_ALERTED );
event &= ~POLLOUT; event &= ~POLLOUT;
} }
if ( event & (POLLERR|POLLHUP) ) if ( event & (POLLERR|POLLHUP) )
@ -329,9 +329,9 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
int status = sock_get_ntstatus( error ); int status = sock_get_ntstatus( error );
if ( !(sock->state & FD_READ) ) if ( !(sock->state & FD_READ) )
async_wake_up( sock->read_q, status ); async_wake_up( &sock->read_q, status );
if ( !(sock->state & FD_WRITE) ) if ( !(sock->state & FD_WRITE) )
async_wake_up( sock->write_q, status ); async_wake_up( &sock->write_q, status );
} }
} }
return event; return event;
@ -508,9 +508,9 @@ static int sock_get_poll_events( struct fd *fd )
/* connecting, wait for writable */ /* connecting, wait for writable */
return POLLOUT; return POLLOUT;
if ( async_queued( sock->read_q ) ) if (async_queued( &sock->read_q ))
{ {
if ( async_waiting( sock->read_q ) ) ev |= POLLIN | POLLPRI; if (async_waiting( &sock->read_q )) ev |= POLLIN | POLLPRI;
} }
else if (smask & FD_READ || (sock->state & FD_WINE_LISTENING && mask & FD_ACCEPT)) else if (smask & FD_READ || (sock->state & FD_WINE_LISTENING && mask & FD_ACCEPT))
ev |= POLLIN | POLLPRI; ev |= POLLIN | POLLPRI;
@ -519,9 +519,9 @@ static int sock_get_poll_events( struct fd *fd )
!(sock->hmask & FD_READ) ) !(sock->hmask & FD_READ) )
ev |= POLLIN; ev |= POLLIN;
if ( async_queued( sock->write_q ) ) if (async_queued( &sock->write_q ))
{ {
if ( async_waiting( sock->write_q ) ) ev |= POLLOUT; if (async_waiting( &sock->write_q )) ev |= POLLOUT;
} }
else if (smask & FD_WRITE) else if (smask & FD_WRITE)
ev |= POLLOUT; ev |= POLLOUT;
@ -549,8 +549,7 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
return 0; return 0;
} }
if (!sock_get_ifchange( sock )) return 0; if (!sock_get_ifchange( sock )) return 0;
if (!sock->ifchange_q && !(sock->ifchange_q = create_async_queue( sock->fd ))) return 0; queue_async( &sock->ifchange_q, async );
queue_async( sock->ifchange_q, async );
set_error( STATUS_PENDING ); set_error( STATUS_PENDING );
return 1; return 1;
default: default:
@ -569,12 +568,10 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
switch (type) switch (type)
{ {
case ASYNC_TYPE_READ: case ASYNC_TYPE_READ:
if (!sock->read_q && !(sock->read_q = create_async_queue( sock->fd ))) return; queue = &sock->read_q;
queue = sock->read_q;
break; break;
case ASYNC_TYPE_WRITE: case ASYNC_TYPE_WRITE:
if (!sock->write_q && !(sock->write_q = create_async_queue( sock->fd ))) return; queue = &sock->write_q;
queue = sock->write_q;
break; break;
default: default:
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
@ -598,7 +595,7 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
{ {
struct sock *sock = get_fd_user( fd ); struct sock *sock = get_fd_user( fd );
/* ignore reselect on ifchange queue */ /* ignore reselect on ifchange queue */
if (sock->ifchange_q != queue) if (&sock->ifchange_q != queue)
sock_reselect( sock ); sock_reselect( sock );
} }
@ -618,11 +615,11 @@ static void sock_destroy( struct object *obj )
if ( sock->deferred ) if ( sock->deferred )
release_object( sock->deferred ); release_object( sock->deferred );
async_wake_up( sock->ifchange_q, STATUS_CANCELLED ); async_wake_up( &sock->ifchange_q, STATUS_CANCELLED );
sock_release_ifchange( sock ); sock_release_ifchange( sock );
free_async_queue( sock->read_q ); free_async_queue( &sock->read_q );
free_async_queue( sock->write_q ); free_async_queue( &sock->write_q );
free_async_queue( sock->ifchange_q ); free_async_queue( &sock->ifchange_q );
if (sock->event) release_object( sock->event ); if (sock->event) release_object( sock->event );
if (sock->fd) if (sock->fd)
{ {
@ -648,10 +645,10 @@ static void init_sock(struct sock *sock)
sock->wparam = 0; sock->wparam = 0;
sock->connect_time = 0; sock->connect_time = 0;
sock->deferred = NULL; sock->deferred = NULL;
sock->read_q = NULL;
sock->write_q = NULL;
sock->ifchange_q = NULL;
sock->ifchange_obj = NULL; sock->ifchange_obj = NULL;
init_async_queue( &sock->read_q );
init_async_queue( &sock->write_q );
init_async_queue( &sock->ifchange_q );
memset( sock->errors, 0, sizeof(sock->errors) ); memset( sock->errors, 0, sizeof(sock->errors) );
} }
@ -1040,7 +1037,7 @@ static void ifchange_wake_up( struct object *obj, unsigned int status )
struct sock *sock = LIST_ENTRY( ptr, struct sock, ifchange_entry ); struct sock *sock = LIST_ENTRY( ptr, struct sock, ifchange_entry );
assert( sock->ifchange_obj ); assert( sock->ifchange_obj );
async_wake_up( sock->ifchange_q, status ); /* issue ifchange notification for the socket */ async_wake_up( &sock->ifchange_q, status ); /* issue ifchange notification for the socket */
sock_release_ifchange( sock ); /* remove socket from list and decrement ifchange refcount */ sock_release_ifchange( sock ); /* remove socket from list and decrement ifchange refcount */
} }
} }