diff options
Diffstat (limited to 'src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5')
3 files changed, 218 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt new file mode 100644 index 0000000000..37d709f121 --- /dev/null +++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(SOURCES + test5.c +) + +add_executable(paltest_criticalsectionfunctions_test5 + ${SOURCES} +) + +add_dependencies(paltest_criticalsectionfunctions_test5 coreclrpal) + +target_link_libraries(paltest_criticalsectionfunctions_test5 + pthread + m + coreclrpal +) diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c new file mode 100644 index 0000000000..8dfa4f5f3d --- /dev/null +++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c @@ -0,0 +1,187 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*===================================================================== +** +** Source: CriticalSectionFunctions/test5/test5.c +** +** Purpose: Attempt to delete a critical section owned by another +** thread. +** +** +**===================================================================*/ +#include <palsuite.h> + +/* + * Tokens 0 and 1 are events. Token 2 is the thread. + */ +#define NUM_TOKENS 3 + +HANDLE hToken[NUM_TOKENS]; +CRITICAL_SECTION CriticalSection; + +BOOL CleanupHelper (HANDLE *hArray, DWORD dwIndex) +{ + BOOL bCHRet; + + bCHRet = CloseHandle(hArray[dwIndex]); + if (!bCHRet) + { + Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during " + "clean up.\nGetLastError returned '%u'.\n", hArray[dwIndex], + GetLastError()); + } + + return (bCHRet); +} + +BOOL Cleanup(HANDLE *hArray, DWORD dwIndex) +{ + BOOL bCRet; + BOOL bCHRet = FALSE; + + while (--dwIndex > 0) + { + bCHRet = CleanupHelper(&hArray[0], dwIndex); + } + + bCRet = CloseHandle(hArray[0]); + if (!bCRet) + { + Trace("PALSUITE ERROR: Unable to execute CloseHandle(%p) during " + "clean up.\nGetLastError returned '%u'.\n", hArray[dwIndex], + GetLastError()); + } + + return (bCRet&&bCHRet); +} + +DWORD PALAPI Thread(LPVOID lpParam) +{ + DWORD dwTRet; + + EnterCriticalSection(&CriticalSection); + + /* signal thread 0 */ + if (0 == SetEvent(hToken[0])) + { + Trace("PALSUITE ERROR: Unable to execute SetEvent(%p) during " + "clean up.\nGetLastError returned '%u'.\n", hToken[0], + GetLastError()); + LeaveCriticalSection(&CriticalSection); + Cleanup (&hToken[0], NUM_TOKENS); + DeleteCriticalSection(&CriticalSection); + Fail(""); + } + + /* wait to be signaled */ + dwTRet = WaitForSingleObject(hToken[1], 10000); + if (WAIT_OBJECT_0 != dwTRet) + + { + Trace("PALSUITE ERROR: WaitForSingleObject(%p,%d) should have " + "returned\nWAIT_OBJECT_0 ('%d'), instead it returned " + "('%d').\nGetLastError returned '%u'.\n", + hToken[1], 10000, WAIT_OBJECT_0, dwTRet, GetLastError()); + LeaveCriticalSection(&CriticalSection); + Cleanup (&hToken[0], NUM_TOKENS); + DeleteCriticalSection(&CriticalSection); + Fail(""); + } + + LeaveCriticalSection(&CriticalSection); + return 0; +} + +int __cdecl main(int argc, char **argv) +{ + DWORD dwThreadId; + DWORD dwMRet; + + if ((PAL_Initialize(argc,argv)) != 0) + { + return(FAIL); + } + + /* thread 0 event */ + hToken[0] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == hToken[0]) + { + Fail("PALSUITE ERROR: CreateEvent call #0 failed. GetLastError " + "returned %u.\n", GetLastError()); + } + + /* thread 1 event */ + hToken[1] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == hToken[1]) + { + Trace("PALSUITE ERROR: CreateEvent call #1 failed. GetLastError " + "returned %u.\n", GetLastError()); + Cleanup(&hToken[0], (NUM_TOKENS - 2)); + Fail(""); + } + + InitializeCriticalSection(&CriticalSection); + + hToken[2] = CreateThread(NULL, + 0, + &Thread, + (LPVOID) NULL, + 0, + &dwThreadId); + if (hToken[2] == NULL) + { + Trace("PALSUITE ERROR: CreateThread call #0 failed. GetLastError " + "returned %u.\n", GetLastError()); + Cleanup(&hToken[0], (NUM_TOKENS - 1)); + DeleteCriticalSection(&CriticalSection); + Fail(""); + } + + /* wait for thread 0 to be signaled */ + dwMRet = WaitForSingleObject(hToken[0], 10000); + if (WAIT_OBJECT_0 != dwMRet) + { + Trace("PALSUITE ERROR: WaitForSingleObject(%p,%d) should have " + "returned\nWAIT_OBJECT_0 ('%d'), instead it returned " + "('%d').\nGetLastError returned '%u'.\n", hToken[0], 10000, + WAIT_OBJECT_0, dwMRet, GetLastError()); + Cleanup(&hToken[0], NUM_TOKENS); + Fail(""); + } + + /* + * Attempt to do delete CriticalSection object owned by other thread + */ + DeleteCriticalSection(&CriticalSection); + + /* signal thread 1 */ + if (0 == SetEvent(hToken[1])) + { + Trace("PALSUITE ERROR: Unable to execute SetEvent(%p) call.\n" + "GetLastError returned '%u'.\n", hToken[1], + GetLastError()); + Cleanup(&hToken[0], NUM_TOKENS); + Fail(""); + } + + dwMRet = WaitForSingleObject(hToken[2], 10000); + if (WAIT_OBJECT_0 != dwMRet) + { + Trace("PALSUITE ERROR: WaitForSingleObject(%p, %d) call " + "returned an unexpected value '%d'.\nGetLastError returned " + "%u.\n", hToken[2], 10000, dwMRet, GetLastError()); + Cleanup(&hToken[0], NUM_TOKENS); + Fail(""); + } + + if (!Cleanup(&hToken[0], NUM_TOKENS)) + { + Fail(""); + } + + PAL_Terminate(); + + return (PASS); +} diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/testinfo.dat b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/testinfo.dat new file mode 100644 index 0000000000..aa1124925b --- /dev/null +++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/testinfo.dat @@ -0,0 +1,12 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. + +Version = 1.0 +Section = threading +Function = CriticalSectionFunctions +Name = Positive test for DeleteCriticalSection +TYPE = DEFAULT +EXE1 = test5 +Description += Attempt to delete a critical section owned by another thread. |