diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
commit | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (patch) | |
tree | e5435159cd1bf0519276363a6fe1663d1721bed3 /src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp | |
parent | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (diff) | |
download | coreclr-05d56390f6d6e680c38788a2b7b4cc683b171d77.tar.gz coreclr-05d56390f6d6e680c38788a2b7b4cc683b171d77.tar.bz2 coreclr-05d56390f6d6e680c38788a2b7b4cc683b171d77.zip |
Imported Upstream version 1.0.0.9127upstream/1.0.0.9127
Diffstat (limited to 'src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp')
-rw-r--r-- | src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp new file mode 100644 index 0000000000..c27db86e5b --- /dev/null +++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp @@ -0,0 +1,190 @@ +// 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/test6/test6.c +** +** Purpose: Attempt to leave a critical section which is 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; + + 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 (hToken[0] == NULL) + { + Fail("PALSUITE ERROR: CreateEvent call #0 failed. GetLastError " + "returned %u.\n", GetLastError()); + } + + /* thread 1 event */ + hToken[1] = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (hToken[1] == NULL) + { + 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 leave critical section which is owned by the other thread. + */ + LeaveCriticalSection(&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); +} |