ntdll: Only queue IO callback if IO is pending in ioqueue_thread_proc().
Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
217ae19d03
commit
fa9bbe8a22
|
@ -2139,6 +2139,24 @@ static void test_tp_io(void)
|
||||||
ok(!userdata.length, "got length %lu\n", userdata.length);
|
ok(!userdata.length, "got length %lu\n", userdata.length);
|
||||||
ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io);
|
ok(userdata.io == io, "expected %p, got %p\n", io, userdata.io);
|
||||||
|
|
||||||
|
userdata.count = 0;
|
||||||
|
pTpStartAsyncIoOperation(io);
|
||||||
|
pTpCancelAsyncIoOperation(io);
|
||||||
|
ret = ReadFile(server, in, sizeof(in), NULL, &ovl);
|
||||||
|
ok(!ret, "wrong ret %d\n", ret);
|
||||||
|
ret = WriteFile(client, out, sizeof(out), &ret_size, NULL);
|
||||||
|
ok(ret, "WriteFile() failed, error %u\n", GetLastError());
|
||||||
|
ok(GetLastError() == ERROR_IO_PENDING, "wrong error %u\n", GetLastError());
|
||||||
|
|
||||||
|
pTpWaitForIoCompletion(io, FALSE);
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
/* Add a sleep to check that callback is not called later. Commented out to
|
||||||
|
* save the test time. */
|
||||||
|
Sleep(200);
|
||||||
|
}
|
||||||
|
ok(userdata.count == 0, "callback ran %u times\n", userdata.count);
|
||||||
|
|
||||||
CloseHandle(ovl.hEvent);
|
CloseHandle(ovl.hEvent);
|
||||||
CloseHandle(client);
|
CloseHandle(client);
|
||||||
CloseHandle(server);
|
CloseHandle(server);
|
||||||
|
|
|
@ -1536,22 +1536,25 @@ static void CALLBACK ioqueue_thread_proc( void *param )
|
||||||
{
|
{
|
||||||
RtlEnterCriticalSection( &io->pool->cs );
|
RtlEnterCriticalSection( &io->pool->cs );
|
||||||
|
|
||||||
--io->u.io.pending_count;
|
TRACE( "pending_count %u.\n", io->u.io.pending_count );
|
||||||
|
|
||||||
if (!array_reserve((void **)&io->u.io.completions, &io->u.io.completion_max,
|
if (io->u.io.pending_count)
|
||||||
io->u.io.completion_count + 1, sizeof(*io->u.io.completions)))
|
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate memory.\n");
|
--io->u.io.pending_count;
|
||||||
RtlLeaveCriticalSection( &io->pool->cs );
|
if (!array_reserve((void **)&io->u.io.completions, &io->u.io.completion_max,
|
||||||
continue;
|
io->u.io.completion_count + 1, sizeof(*io->u.io.completions)))
|
||||||
|
{
|
||||||
|
ERR( "Failed to allocate memory.\n" );
|
||||||
|
RtlLeaveCriticalSection( &io->pool->cs );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
completion = &io->u.io.completions[io->u.io.completion_count++];
|
||||||
|
completion->iosb = iosb;
|
||||||
|
completion->cvalue = value;
|
||||||
|
|
||||||
|
tp_object_submit( io, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
completion = &io->u.io.completions[io->u.io.completion_count++];
|
|
||||||
completion->iosb = iosb;
|
|
||||||
completion->cvalue = value;
|
|
||||||
|
|
||||||
tp_object_submit( io, FALSE );
|
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &io->pool->cs );
|
RtlLeaveCriticalSection( &io->pool->cs );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2525,6 +2528,8 @@ void WINAPI TpCancelAsyncIoOperation( TP_IO *io )
|
||||||
|
|
||||||
RtlEnterCriticalSection( &this->pool->cs );
|
RtlEnterCriticalSection( &this->pool->cs );
|
||||||
|
|
||||||
|
TRACE("pending_count %u.\n", this->u.io.pending_count);
|
||||||
|
|
||||||
this->u.io.pending_count--;
|
this->u.io.pending_count--;
|
||||||
if (object_is_finished( this, TRUE ))
|
if (object_is_finished( this, TRUE ))
|
||||||
RtlWakeAllConditionVariable( &this->group_finished_event );
|
RtlWakeAllConditionVariable( &this->group_finished_event );
|
||||||
|
|
Loading…
Reference in New Issue