dinput/tests: Enforce ordering of concurrent read IRPs.
This commit is contained in:
parent
e2dffb8eb0
commit
3e79b8d6eb
1 changed files with 19 additions and 11 deletions
|
@ -348,13 +348,13 @@ static void irp_queue_push( struct irp_queue *queue, IRP *irp )
|
|||
KeReleaseSpinLock( &queue->lock, irql );
|
||||
}
|
||||
|
||||
static void irp_queue_clear( struct irp_queue *queue )
|
||||
static void irp_queue_complete( struct irp_queue *queue, BOOL delete )
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
while ((irp = irp_queue_pop( queue )))
|
||||
{
|
||||
irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
||||
if (delete) irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
}
|
||||
}
|
||||
|
@ -373,6 +373,7 @@ struct input_queue
|
|||
struct hid_expect *end;
|
||||
struct hid_expect *buffer;
|
||||
struct irp_queue pending;
|
||||
struct irp_queue completed;
|
||||
};
|
||||
|
||||
static void input_queue_init( struct input_queue *queue, BOOL is_polled )
|
||||
|
@ -384,6 +385,7 @@ static void input_queue_init( struct input_queue *queue, BOOL is_polled )
|
|||
queue->pos = queue->buffer;
|
||||
queue->end = queue->buffer;
|
||||
irp_queue_init( &queue->pending );
|
||||
irp_queue_init( &queue->completed );
|
||||
}
|
||||
|
||||
static void input_queue_cleanup( struct input_queue *queue )
|
||||
|
@ -416,7 +418,11 @@ static NTSTATUS input_queue_read( struct input_queue *queue, IRP *irp )
|
|||
KIRQL irql;
|
||||
|
||||
KeAcquireSpinLock( &queue->lock, &irql );
|
||||
if (input_queue_read_locked( queue, irp )) status = STATUS_SUCCESS;
|
||||
if (input_queue_read_locked( queue, irp ))
|
||||
{
|
||||
irp_queue_push( &queue->completed, irp );
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
IoMarkIrpPending( irp );
|
||||
|
@ -430,13 +436,10 @@ static NTSTATUS input_queue_read( struct input_queue *queue, IRP *irp )
|
|||
|
||||
static void input_queue_reset( struct input_queue *queue, void *in_buf, ULONG in_size )
|
||||
{
|
||||
struct irp_queue completed;
|
||||
ULONG remaining;
|
||||
KIRQL irql;
|
||||
IRP *irp;
|
||||
|
||||
irp_queue_init( &completed );
|
||||
|
||||
KeAcquireSpinLock( &queue->lock, &irql );
|
||||
remaining = queue->end - queue->pos;
|
||||
queue->pos = queue->buffer;
|
||||
|
@ -447,13 +450,13 @@ static void input_queue_reset( struct input_queue *queue, void *in_buf, ULONG in
|
|||
while (!queue->is_polled && queue->pos < queue->end && (irp = irp_queue_pop( &queue->pending )))
|
||||
{
|
||||
input_queue_read_locked( queue, irp );
|
||||
irp_queue_push( &completed, irp );
|
||||
irp_queue_push( &queue->completed, irp );
|
||||
}
|
||||
KeReleaseSpinLock( &queue->lock, irql );
|
||||
|
||||
if (!queue->is_polled) ok( !remaining, "unread input\n" );
|
||||
|
||||
while ((irp = irp_queue_pop( &completed ))) IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
irp_queue_complete( &queue->completed, FALSE );
|
||||
}
|
||||
|
||||
struct device
|
||||
|
@ -721,7 +724,8 @@ static NTSTATUS pdo_pnp( DEVICE_OBJECT *device, IRP *irp )
|
|||
state = (code == IRP_MN_START_DEVICE || code == IRP_MN_CANCEL_REMOVE_DEVICE) ? 0 : PNP_DEVICE_REMOVED;
|
||||
KeAcquireSpinLock( &impl->base.lock, &irql );
|
||||
impl->base.state = state;
|
||||
irp_queue_clear( &impl->input_queue.pending );
|
||||
irp_queue_complete( &impl->input_queue.pending, TRUE );
|
||||
irp_queue_complete( &impl->input_queue.completed, TRUE );
|
||||
KeReleaseSpinLock( &impl->base.lock, irql );
|
||||
if (code != IRP_MN_REMOVE_DEVICE) status = STATUS_SUCCESS;
|
||||
else
|
||||
|
@ -1087,7 +1091,10 @@ static NTSTATUS pdo_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
|
|||
ok( !in_size, "got input size %lu\n", in_size );
|
||||
ok( out_size == expected_size, "got output size %lu\n", out_size );
|
||||
status = input_queue_read( &impl->input_queue, irp );
|
||||
break;
|
||||
irp_queue_complete( &impl->input_queue.completed, FALSE );
|
||||
|
||||
winetest_pop_context();
|
||||
return status;
|
||||
}
|
||||
|
||||
case IOCTL_HID_WRITE_REPORT:
|
||||
|
@ -1277,7 +1284,8 @@ static NTSTATUS pdo_handle_ioctl( struct phys_device *impl, IRP *irp, ULONG code
|
|||
case IOCTL_WINETEST_REMOVE_DEVICE:
|
||||
KeAcquireSpinLock( &impl->base.lock, &irql );
|
||||
impl->base.state = PNP_DEVICE_REMOVED;
|
||||
irp_queue_clear( &impl->input_queue.pending );
|
||||
irp_queue_complete( &impl->input_queue.pending, TRUE );
|
||||
irp_queue_complete( &impl->input_queue.completed, TRUE );
|
||||
KeReleaseSpinLock( &impl->base.lock, irql );
|
||||
impl->pending_remove = irp;
|
||||
IoMarkIrpPending( irp );
|
||||
|
|
Loading…
Add table
Reference in a new issue