server: Check for an existing serial wait ioctl within the ioctl handler.

This commit is contained in:
Elizabeth Figura 2024-05-28 18:41:05 -05:00 committed by Alexandre Julliard
parent 25a02d894f
commit 6b7834d407
Notes: Alexandre Julliard 2024-06-18 23:12:34 +02:00
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/-/merge_requests/5862
4 changed files with 10 additions and 47 deletions

View file

@ -452,21 +452,7 @@ static NTSTATUS get_status(int fd, SERIAL_STATUS* ss)
return status;
}
static void stop_waiting( HANDLE handle )
{
unsigned int status;
SERVER_START_REQ( set_serial_info )
{
req->handle = wine_server_obj_handle( handle );
req->flags = SERIALINFO_PENDING_WAIT;
if ((status = wine_server_call( req )))
ERR("failed to clear waiting state: %#x\n", status);
}
SERVER_END_REQ;
}
static NTSTATUS get_wait_mask(HANDLE hDevice, UINT *mask, UINT *cookie, BOOL *pending_write, BOOL start_wait)
static NTSTATUS get_wait_mask( HANDLE hDevice, UINT *mask, UINT *cookie, BOOL *pending_write )
{
unsigned int status;
@ -474,7 +460,6 @@ static NTSTATUS get_wait_mask(HANDLE hDevice, UINT *mask, UINT *cookie, BOOL *pe
{
req->handle = wine_server_obj_handle( hDevice );
req->flags = pending_write ? SERIALINFO_PENDING_WRITE : 0;
if (start_wait) req->flags |= SERIALINFO_PENDING_WAIT;
if (!(status = wine_server_call( req )))
{
*mask = reply->eventmask;
@ -1126,7 +1111,7 @@ static BOOL async_wait_proc( void *user, ULONG_PTR *info, unsigned int *status )
}
else
{
get_wait_mask( commio->io.handle, &dummy, &cookie, (commio->evtmask & EV_TXEMPTY) ? &commio->pending_write : NULL, FALSE );
get_wait_mask( commio->io.handle, &dummy, &cookie, (commio->evtmask & EV_TXEMPTY) ? &commio->pending_write : NULL );
if (commio->cookie != cookie)
{
*commio->events = 0;
@ -1143,7 +1128,6 @@ static BOOL async_wait_proc( void *user, ULONG_PTR *info, unsigned int *status )
if (needs_close) close( fd );
}
stop_waiting( commio->io.handle );
release_fileio( &commio->io );
return TRUE;
}
@ -1161,7 +1145,7 @@ static NTSTATUS wait_on( HANDLE handle, int fd, HANDLE event, PIO_APC_ROUTINE ap
commio->events = out_buffer;
commio->pending_write = 0;
status = get_wait_mask( handle, &commio->evtmask, &commio->cookie, (commio->evtmask & EV_TXEMPTY) ? &commio->pending_write : NULL, TRUE );
status = get_wait_mask( handle, &commio->evtmask, &commio->cookie, (commio->evtmask & EV_TXEMPTY) ? &commio->pending_write : NULL );
if (status)
{
free( commio );

View file

@ -3035,7 +3035,6 @@ struct set_serial_info_reply
struct reply_header __header;
};
#define SERIALINFO_PENDING_WRITE 0x04
#define SERIALINFO_PENDING_WAIT 0x08
struct cancel_sync_request
@ -6534,7 +6533,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 806
#define SERVER_PROTOCOL_VERSION 807
/* ### protocol_version end ### */

View file

@ -2256,7 +2256,6 @@ enum message_type
int flags; /* bitmask to set values (see below) */
@END
#define SERIALINFO_PENDING_WRITE 0x04
#define SERIALINFO_PENDING_WAIT 0x08
/* Cancel all sync io on a thread */
@REQ(cancel_sync)

View file

@ -78,7 +78,6 @@ struct serial
unsigned int eventmask;
unsigned int generation; /* event mask change counter */
unsigned int pending_write : 1;
unsigned int pending_wait : 1;
struct termios original;
@ -144,7 +143,6 @@ struct object *create_serial( struct fd *fd )
serial->eventmask = 0;
serial->generation = 0;
serial->pending_write = 0;
serial->pending_wait = 0;
memset( &serial->timeouts, 0, sizeof(serial->timeouts) );
init_async_queue( &serial->wait_q );
serial->fd = (struct fd *)grab_object( fd );
@ -250,6 +248,12 @@ static void serial_ioctl( struct fd *fd, ioctl_code_t code, struct async *async
{
struct wait_req *req;
if (async_queued( &serial->wait_q ))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!(req = mem_alloc(sizeof(*req))))
return;
@ -329,17 +333,6 @@ DECL_HANDLER(get_serial_info)
if ((serial = get_serial_obj( current->process, req->handle, 0 )))
{
if (req->flags & SERIALINFO_PENDING_WAIT)
{
if (serial->pending_wait)
{
release_object( serial );
set_error( STATUS_INVALID_PARAMETER );
return;
}
serial->pending_wait = 1;
}
/* event mask */
reply->eventmask = serial->eventmask;
reply->cookie = serial->generation;
@ -359,18 +352,6 @@ DECL_HANDLER(set_serial_info)
if ((serial = get_serial_obj( current->process, req->handle, 0 )))
{
if (req->flags & SERIALINFO_PENDING_WAIT)
{
if (!serial->pending_wait)
{
release_object( serial );
set_error( STATUS_INVALID_PARAMETER );
return;
}
serial->pending_wait = 0;
}
/* pending write */
if (req->flags & SERIALINFO_PENDING_WRITE)
serial->pending_write = 1;