Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

231 lines
5.6 KiB
C

/*=====================================================================
**
** Source: test2.c
**
** Purpose: Tests that APCs are not executed if a thread never enters an
** alertable state after they are queued.
**
**
** Copyright (c) 2002 Microsoft Corporation. All rights reserved.
**
** The use and distribution terms for this software are contained in the file
** named license.txt, which can be found in the root of this distribution.
** By using this software in any fashion, you are agreeing to be bound by the
** terms of this license.
**
** You must not remove this notice, or any other, from this software.
**
**
**===================================================================*/
#include <palsuite.h>
const int ChildThreadSleepTime = 2000;
const int InterruptTime = 1000;
DWORD ChildThread;
BOOL InAPC;
/* synchronization events */
static HANDLE hSyncEvent1 = NULL;
static HANDLE hSyncEvent2 = NULL;
/* thread result because we have no GetExitCodeThread() API */
static BOOL bThreadResult = FAIL;
VOID PALAPI APCFunc(ULONG_PTR dwParam)
{
InAPC = TRUE;
}
DWORD PALAPI SleeperProc(LPVOID lpParameter)
{
DWORD ret;
/* signal the main thread that we're ready to proceed */
if( ! SetEvent( hSyncEvent1 ) )
{
Trace( "ERROR:%lu:SetEvent() call failed\n", GetLastError() );
bThreadResult = FAIL;
goto done;
}
/* wait for notification from the main thread */
ret = WaitForSingleObject( hSyncEvent2, 20000 );
if( ret != WAIT_OBJECT_0 )
{
Trace( "ERROR:WaitForSingleObject() returned %lu, "
"expected WAIT_OBJECT_0\n",
ret );
bThreadResult = FAIL;
goto done;
}
/* call our sleep function */
Sleep( ChildThreadSleepTime );
/* success if we reach here */
bThreadResult = PASS;
done:
/* signal the main thread that we're finished */
if( ! SetEvent( hSyncEvent1 ) )
{
Trace( "ERROR:%lu:SetEvent() call failed\n", GetLastError() );
bThreadResult = FAIL;
}
/* return success or failure */
return bThreadResult;
}
int __cdecl main (int argc, char **argv)
{
/* local variables */
HANDLE hThread = 0;
int ret;
BOOL bResult = FAIL;
/* initialize the PAL */
if (0 != (PAL_Initialize(argc, argv)))
{
return FAIL;
}
InAPC = FALSE;
/* create a pair of synchronization events to coordinate our threads */
hSyncEvent1 = CreateEvent( NULL, FALSE, FALSE, NULL );
if( hSyncEvent1 == NULL )
{
Trace( "ERROR:%lu:CreateEvent() call failed\n", GetLastError() );
goto cleanup;
}
hSyncEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL );
if( hSyncEvent2 == NULL )
{
Trace( "ERROR:%lu:CreateEvent() call failed\n", GetLastError() );
goto cleanup;
}
/* create a child thread */
hThread = CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)SleeperProc,
0,
0,
&ChildThread);
if (hThread == NULL)
{
Trace( "ERROR:%lu:CreateThread() call failed\n",
GetLastError());
goto cleanup;
}
/* wait on our synchronization event to ensure the thread is running */
ret = WaitForSingleObject( hSyncEvent1, 20000 );
if( ret != WAIT_OBJECT_0 )
{
Trace( "ERROR:WaitForSingleObject() returned %lu, "
"expected WAIT_OBJECT_0\n",
ret );
goto cleanup;
}
/* queue a user APC on the child thread */
ret = QueueUserAPC(APCFunc, hThread, 0);
if (ret == 0)
{
Trace( "ERROR:%lu:QueueUserAPC() call failed\n",
GetLastError());
goto cleanup;
}
/* signal the child thread to continue */
if( ! SetEvent( hSyncEvent2 ) )
{
Trace( "ERROR:%lu:SetEvent() call failed\n", GetLastError() );
goto cleanup;
}
/* wait on our synchronization event to ensure the other thread is done */
ret = WaitForSingleObject( hSyncEvent1, 20000 );
if( ret != WAIT_OBJECT_0 )
{
Trace( "ERROR:WaitForSingleObject() returned %lu, "
"expected WAIT_OBJECT_0\n",
ret );
goto cleanup;
}
/* check that the thread executed successfully */
if( bThreadResult == FAIL )
{
goto cleanup;
}
/* check whether the APC function was executed */
if( InAPC )
{
Trace( "FAIL:APC function was executed but shouldn't have been\n" );
goto cleanup;
}
/* success if we reach here */
bResult = PASS;
cleanup:
/* wait for the other thread to finish */
if( hThread != NULL )
{
ret = WaitForSingleObject( hThread, INFINITE );
if (ret == WAIT_FAILED)
{
Trace( "ERROR:%lu:WaitForSingleObject() returned %lu, "
"expected WAIT_OBJECT_0\n",
ret );
bResult = FAIL;
}
}
/* close our synchronization handles */
if( hSyncEvent1 != NULL )
{
if( ! CloseHandle( hSyncEvent1 ) )
{
Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() );
bResult = FAIL;
}
}
if( hSyncEvent2 != NULL )
{
if( ! CloseHandle( hSyncEvent2 ) )
{
Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() );
bResult = FAIL;
}
}
if( bResult == FAIL )
{
Fail( "test failed\n" );
}
/* terminate the PAL */
PAL_Terminate();
/* return success */
return PASS;
}