SemaphoreImpl::SemaphoreImpl(int n, int max) { poco_assert (n >= 0 && max > 0 && n <= max); _sema = CreateSemaphoreW(NULL, n, max, NULL); if (!_sema) { throw SystemException("cannot create semaphore"); } }
HOOKFUNC HANDLE WINAPI MyCreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCWSTR lpName) { HANDLE rv = CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName); debuglog(LCF_SYNCOBJ, __FUNCTION__ " returned 0x%X.\n", rv); EnterCriticalSection(&s_handleCS); std::set<HANDLE>& handles = s_threadIdHandles[GetCurrentThreadId()]; handles.insert(rv); LeaveCriticalSection(&s_handleCS); return rv; }
/* Entry Point for child thread. */ DWORD PALAPI WaiterProc(LPVOID lpParameter) { HANDLE Semaphore; UINT64 OldTimeStamp; UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; /* Create a semaphore that is not in the signalled state */ Semaphore = CreateSemaphoreW(NULL, 0, 1, NULL); if (Semaphore == NULL) { Fail("Failed to create semaphore! GetLastError returned %d.\n", GetLastError()); } Alertable = (BOOL) lpParameter; LARGE_INTEGER performanceFrequency; if (!QueryPerformanceFrequency(&performanceFrequency)) { Fail("Failed to query performance frequency!"); } OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = WaitForMultipleObjectsEx(1, &Semaphore, FALSE, ChildThreadWaitTime, Alertable); NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) { Fail("Expected the interrupted wait to return WAIT_IO_COMPLETION.\n" "Got %d\n", ret); } else if (!Alertable && ret != WAIT_TIMEOUT) { Fail("WaitForMultipleObjectsEx did not timeout.\n" "Expected return of WAIT_TIMEOUT, got %d.\n", ret); } ThreadWaitDelta = NewTimeStamp - OldTimeStamp; ret = CloseHandle(Semaphore); if (!ret) { Fail("Unable to close handle to semaphore!\n" "GetLastError returned %d\n", GetLastError()); } return 0; }
HOOKFUNC HANDLE WINAPI MyCreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) { ENTER(); HANDLE rv = CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName); LEAVE(rv); EnterCriticalSection(&s_handleCS); std::set<HANDLE>& handles = s_threadIdHandles[GetCurrentThreadId()]; handles.insert(rv); LeaveCriticalSection(&s_handleCS); return rv; }
HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) { // don't allow making handles on empty keys if (key.isEmpty()) return 0; // Create it if it doesn't already exists. if (semaphore == 0) { QString safeName = makeKeyFileName(); QT_WA({ semaphore = CreateSemaphoreW(0, initialValue, MAXLONG, (TCHAR*)safeName.utf16()); }, {
HANDLE MicroMockCreateGlobalSemaphore(const char* name, unsigned int highWaterCount) { WCHAR temp[MAX_PATH]; if(MultiByteToWideChar(CP_ACP, 0, name, -1, temp,MAX_PATH)==0) { return NULL; } else { return CreateSemaphoreW(NULL, highWaterCount,highWaterCount, temp); } }
/*! \internal Setup the semaphore */ HANDLE QSystemLockPrivate::handle() { // don't allow making handles on empty keys if (key.isEmpty()) return 0; // Create it if it doesn't already exists. if (semaphore == 0) { QString safeName = makeKeyFileName(); QT_WA({ semaphore = CreateSemaphoreW(0, MAX_LOCKS, MAX_LOCKS, (TCHAR*)safeName.utf16()); }, {
LOCK_HANDLE Lock_Init(void) { /* Codes_SRS_LOCK_10_002: [Lock_Init on success shall return a valid lock handle which should be a non NULL value] */ /* Codes_SRS_LOCK_10_003: [Lock_Init on error shall return NULL ] */ HANDLE result = CreateSemaphoreW(NULL, 1, 1, NULL); if (result == NULL) { LogError("CreateSemaphore failed."); } return (LOCK_HANDLE)result; }
inline handle create_anonymous_semaphore(long initial_count,long max_count) { #if !defined(BOOST_NO_ANSI_APIS) handle const res=CreateSemaphoreA(0,initial_count,max_count,0); #else handle const res=CreateSemaphoreW(0,initial_count,max_count,0); #endif if(!res) { boost::throw_exception(thread_resource_error()); } return res; }
//---------------------------------------------------------------------------------------- amf_handle AMF_CDECL_CALL amf_create_semaphore(amf_long iInitCount, amf_long iMaxCount, const wchar_t* pName) { if(iMaxCount == 0) { return NULL; } #if defined(METRO_APP) return CreateSemaphoreEx(NULL, iInitCount, iMaxCount, pName, 0, STANDARD_RIGHTS_ALL | SEMAPHORE_MODIFY_STATE); #else return CreateSemaphoreW(NULL, iInitCount, iMaxCount, pName); #endif }
HANDLE APIENTRY CreateSemaphoreA( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName ) /*++ Routine Description: ANSI thunk to CreateSemaphoreW --*/ { PUNICODE_STRING Unicode; ANSI_STRING AnsiString; NTSTATUS Status; LPCWSTR NameBuffer; NameBuffer = NULL; if ( ARGUMENT_PRESENT(lpName) ) { Unicode = &NtCurrentTeb()->StaticUnicodeString; RtlInitAnsiString(&AnsiString,lpName); Status = RtlAnsiStringToUnicodeString(Unicode,&AnsiString,FALSE); if ( !NT_SUCCESS(Status) ) { if ( Status == STATUS_BUFFER_OVERFLOW ) { SetLastError(ERROR_FILENAME_EXCED_RANGE); } else { BaseSetLastNTError(Status); } return NULL; } NameBuffer = (LPCWSTR)Unicode->Buffer; } return CreateSemaphoreW( lpSemaphoreAttributes, lInitialCount, lMaximumCount, NameBuffer ); }
static HRESULT WINAPI BaseMemAllocator_Commit(IMemAllocator * iface) { BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr; TRACE("(%p)->()\n", This); EnterCriticalSection(This->pCritSect); { if (!This->props.cbAlign) hr = VFW_E_BADALIGN; else if (!This->props.cbBuffer) hr = VFW_E_SIZENOTSET; else if (!This->props.cBuffers) hr = VFW_E_BUFFER_NOTSET; else if (This->bDecommitQueued && This->bCommitted) { This->bDecommitQueued = FALSE; hr = S_OK; } else if (This->bCommitted) hr = S_OK; else { if (!(This->hSemWaiting = CreateSemaphoreW(NULL, This->props.cBuffers, This->props.cBuffers, NULL))) { ERR("Couldn't create semaphore (error was %u)\n", GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = This->fnAlloc(iface); if (SUCCEEDED(hr)) This->bCommitted = TRUE; else ERR("fnAlloc failed with error 0x%x\n", hr); } } } LeaveCriticalSection(This->pCritSect); return hr; }
asCThreadReadWriteLock::asCThreadReadWriteLock() { #if defined AS_POSIX_THREADS int r = pthread_rwlock_init(&lock, 0); asASSERT( r == 0 ); UNUSED_VAR(r); #elif defined AS_WINDOWS_THREADS #if defined(_MSC_VER) && (WINAPI_FAMILY & WINAPI_FAMILY_PHONE_APP) // Only the Ex versions are available on Windows Store // Create a semaphore to allow up to maxReaders simultaneous readers readLocks = CreateSemaphoreExW(NULL, maxReaders, maxReaders, 0, 0, 0); // Create a critical section to synchronize writers InitializeCriticalSectionEx(&writeLock, 4000, 0); #else readLocks = CreateSemaphoreW(NULL, maxReaders, maxReaders, 0); InitializeCriticalSection(&writeLock); #endif #endif }
static HRESULT WINAPI BaseMemAllocator_Commit(IMemAllocator * iface) { BaseMemAllocator *This = (BaseMemAllocator *)iface; HRESULT hr; TRACE("(%p)->()\n", This); EnterCriticalSection(&This->csState); { if (!This->pProps) hr = VFW_E_SIZENOTSET; else if (This->bCommitted) hr = S_OK; else if (This->bDecommitQueued) { This->bDecommitQueued = FALSE; hr = S_OK; } else { if (!(This->hSemWaiting = CreateSemaphoreW(NULL, This->pProps->cBuffers, This->pProps->cBuffers, NULL))) { ERR("Couldn't create semaphore (error was %ld)\n", GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError()); } else { hr = This->fnAlloc(iface); if (SUCCEEDED(hr)) This->bCommitted = TRUE; else ERR("fnAlloc failed with error 0x%lx\n", hr); } } } LeaveCriticalSection(&This->csState); return hr; }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(%p, %u, %p) not fully implemented\n", (LPVOID)hinstDLL, fdwReason, lpvReserved); switch(fdwReason) { case DLL_PROCESS_ATTACH: { HKEY hKey; LONG r; DisableThreadLibraryCalls(hinstDLL); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPowerCfgSubKey, 0, KEY_READ | KEY_WRITE, &hKey); if (r != ERROR_SUCCESS) { TRACE("Couldn't open registry key HKLM\\%s, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey)); } else { BYTE lpValue[40]; DWORD cbValue = sizeof(lpValue); r = RegQueryValueExW(hKey, szLastID, 0, 0, lpValue, &cbValue); if (r != ERROR_SUCCESS) { TRACE("Couldn't open registry entry HKLM\\%s\\LastID, using some sane(?) defaults\n", debugstr_w(szPowerCfgSubKey)); } RegCloseKey(hKey); } PPRegSemaphore = CreateSemaphoreW(NULL, 1, 1, szSemaphoreName); if (PPRegSemaphore == (HANDLE)NULL) { ERR("Couldn't create Semaphore: %u\n", GetLastError()); return FALSE; } break; } case DLL_PROCESS_DETACH: CloseHandle(PPRegSemaphore); break; } return TRUE; }
bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == m_lock_mode) return true; if (m_lock_mode != 0) unlock(); if (m_semaphore_hnd == 0) { QFileInfo fi(*this); QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX) + fi.absoluteFilePath().toLower(); QT_WA( { m_semaphore_hnd = CreateSemaphoreW(0, SEMAPHORE_MAX, SEMAPHORE_MAX, (TCHAR*)sem_name.utf16()); } , {
/************************************************************************* * SHGlobalCounterCreateNamedW [SHLWAPI.423] * * Unicode version of SHGlobalCounterCreateNamedA. */ HANDLE WINAPI SHGlobalCounterCreateNamedW(LPCWSTR lpszName, DWORD iInitial) { static const WCHAR szPrefix[] = { 's', 'h', 'e', 'l', 'l', '.', '\0' }; const int iPrefixLen = 6; WCHAR szBuff[MAX_PATH]; const int iBuffLen = sizeof(szBuff)/sizeof(WCHAR); SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sAttr, *pSecAttr; HANDLE hRet; TRACE("(%s,%d)\n", debugstr_w(lpszName), iInitial); /* Create Semaphore name */ memcpy(szBuff, szPrefix, (iPrefixLen + 1) * sizeof(WCHAR)); if (lpszName) StrCpyNW(szBuff + iPrefixLen, lpszName, iBuffLen - iPrefixLen); /* Initialise security attributes */ pSecAttr = CreateAllAccessSecurityAttributes(&sAttr, &sd, 0); if (!(hRet = CreateSemaphoreW(pSecAttr , iInitial, MAXLONG, szBuff))) hRet = OpenSemaphoreW(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, 0, szBuff); return hRet; }
HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName) { return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, NULL); }
bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == m_lock_mode) return true; if (m_lock_mode != 0) unlock(); if (m_semaphore_hnd == 0) { QFileInfo fi(*this); QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX) + fi.absoluteFilePath().toLower(); m_semaphore_hnd = CreateSemaphoreW(0, SEMAPHORE_MAX, SEMAPHORE_MAX, (TCHAR*)sem_name.utf16()); if (m_semaphore_hnd == 0) { qWarning("QtLockedFile::lock(): CreateSemaphore: %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } bool gotMutex = false; int decrement; if (mode == ReadLock) { decrement = 1; } else { decrement = SEMAPHORE_MAX; if (m_mutex_hnd == 0) { QFileInfo fi(*this); QString mut_name = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); m_mutex_hnd = CreateMutexW(NULL, FALSE, (TCHAR*)mut_name.utf16()); if (m_mutex_hnd == 0) { qWarning("QtLockedFile::lock(): CreateMutex: %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } DWORD res = WaitForSingleObject(m_mutex_hnd, block ? INFINITE : 0); if (res == WAIT_TIMEOUT) return false; if (res == WAIT_FAILED) { qWarning("QtLockedFile::lock(): WaitForSingleObject (mutex): %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } gotMutex = true; } for (int i = 0; i < decrement; ++i) { DWORD res = WaitForSingleObject(m_semaphore_hnd, block ? INFINITE : 0); if (res == WAIT_TIMEOUT) { if (i) { // A failed nonblocking rw locking. Undo changes to semaphore. if (ReleaseSemaphore(m_semaphore_hnd, i, NULL) == 0) { qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", errorCodeToString(GetLastError()).toLatin1().constData()); // Fall through } } if (gotMutex) ReleaseMutex(m_mutex_hnd); return false; } if (res != WAIT_OBJECT_0) { if (gotMutex) ReleaseMutex(m_mutex_hnd); qWarning("QtLockedFile::lock(): WaitForSingleObject (semaphore): %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } m_lock_mode = mode; if (gotMutex) ReleaseMutex(m_mutex_hnd); return true; }
Semaphore::Semaphore(const Semaphore& rhs) { m_nCount = rhs.m_nCount; m_nMaxCount = rhs.m_nMaxCount; m_hSemaphore = CreateSemaphoreW(NULL, m_nCount, m_nMaxCount, NULL); }
static void test_tp_disassociate(void) { TP_CALLBACK_ENVIRON environment; TP_CLEANUP_GROUP *group; HANDLE semaphores[2]; NTSTATUS status; TP_POOL *pool; TP_WORK *work; DWORD result; semaphores[0] = CreateSemaphoreW(NULL, 0, 1, NULL); ok(semaphores[0] != NULL, "failed to create semaphore\n"); semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL); ok(semaphores[1] != NULL, "failed to create semaphore\n"); /* allocate new threadpool and cleanup group */ pool = NULL; status = pTpAllocPool(&pool, NULL); ok(!status, "TpAllocPool failed with status %x\n", status); ok(pool != NULL, "expected pool != NULL\n"); group = NULL; status = pTpAllocCleanupGroup(&group); ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); ok(group != NULL, "expected pool != NULL\n"); /* test TpDisassociateCallback on work objects without group */ work = NULL; memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; status = pTpAllocWork(&work, disassociate_cb, semaphores, &environment); ok(!status, "TpAllocWork failed with status %x\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpWaitForWork(work, FALSE); result = WaitForSingleObject(semaphores[1], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); pTpReleaseWork(work); /* test TpDisassociateCallback on work objects with group (1) */ work = NULL; memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work, disassociate_cb, semaphores, &environment); ok(!status, "TpAllocWork failed with status %x\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpWaitForWork(work, FALSE); result = WaitForSingleObject(semaphores[1], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); /* test TpDisassociateCallback on work objects with group (2) */ work = NULL; memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; environment.CleanupGroup = group; status = pTpAllocWork(&work, disassociate2_cb, semaphores, &environment); ok(!status, "TpAllocWork failed with status %x\n", status); ok(work != NULL, "expected work != NULL\n"); pTpPostWork(work); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); result = WaitForSingleObject(semaphores[0], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); /* test TpDisassociateCallback on simple callbacks */ memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; environment.CleanupGroup = group; status = pTpSimpleTryPost(disassociate3_cb, semaphores, &environment); ok(!status, "TpSimpleTryPost failed with status %x\n", status); pTpReleaseCleanupGroupMembers(group, FALSE, NULL); ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); result = WaitForSingleObject(semaphores[0], 1000); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); /* cleanup */ pTpReleaseCleanupGroup(group); pTpReleasePool(pool); CloseHandle(semaphores[0]); CloseHandle(semaphores[1]); }
UserSemaphore::UserSemaphore( uint32 maximumCount, uint32 initialCount ) : _semaphore( CreateSemaphoreW( nullptr, static_cast<LONG>( initialCount ), static_cast<LONG>( maximumCount ), nullptr ) ) {}
Semaphore::Semaphore(int initsize) : m_nCount(initsize) { m_hSemaphore = CreateSemaphoreW(NULL, initsize, initsize, NULL); }
static void test_tp_multi_wait(void) { TP_CALLBACK_ENVIRON environment; HANDLE semaphores[512]; TP_WAIT *waits[512]; LARGE_INTEGER when; HANDLE semaphore; NTSTATUS status; TP_POOL *pool; DWORD result; int i; semaphore = CreateSemaphoreW(NULL, 0, 512, NULL); ok(semaphore != NULL, "failed to create semaphore\n"); multi_wait_info.semaphore = semaphore; /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); ok(!status, "TpAllocPool failed with status %x\n", status); ok(pool != NULL, "expected pool != NULL\n"); memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; /* create semaphores and corresponding wait objects */ for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { semaphores[i] = CreateSemaphoreW(NULL, 0, 1, NULL); ok(semaphores[i] != NULL, "failed to create semaphore %i\n", i); waits[i] = NULL; status = pTpAllocWait(&waits[i], multi_wait_cb, (void *)(DWORD_PTR)i, &environment); ok(!status, "TpAllocWait failed with status %x\n", status); ok(waits[i] != NULL, "expected waits[%d] != NULL\n", i); pTpSetWait(waits[i], semaphores[i], NULL); } /* release all semaphores and wait for callback */ for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { multi_wait_info.result = 0; ReleaseSemaphore(semaphores[i], 1, NULL); result = WaitForSingleObject(semaphore, 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(multi_wait_info.result == i, "expected result %d, got %u\n", i, multi_wait_info.result); pTpSetWait(waits[i], semaphores[i], NULL); } /* repeat the same test in reverse order */ for (i = sizeof(semaphores)/sizeof(semaphores[0]) - 1; i >= 0; i--) { multi_wait_info.result = 0; ReleaseSemaphore(semaphores[i], 1, NULL); result = WaitForSingleObject(semaphore, 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(multi_wait_info.result == i, "expected result %d, got %u\n", i, multi_wait_info.result); pTpSetWait(waits[i], semaphores[i], NULL); } /* test timeout of wait objects */ multi_wait_info.result = 0; for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { when.QuadPart = (ULONGLONG)50 * -10000; pTpSetWait(waits[i], semaphores[i], &when); } for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { result = WaitForSingleObject(semaphore, 150); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); } ok(multi_wait_info.result >> 16, "expected multi_wait_info.result >> 16 != 0\n"); /* destroy the wait objects and semaphores while waiting */ for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { pTpSetWait(waits[i], semaphores[i], NULL); } Sleep(50); for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++) { pTpReleaseWait(waits[i]); NtClose(semaphores[i]); } pTpReleasePool(pool); CloseHandle(semaphore); }
Semaphore::Semaphore(int initsize, int maxsize) : m_nCount(initsize), m_nMaxCount(maxsize) { m_hSemaphore = CreateSemaphoreW(NULL, initsize, maxsize, NULL); }
DWORD PALAPI TestThread(PVOID pArg) { BOOL bRet; DWORD dwRet; PROCESS_INFORMATION pi; STARTUPINFO si; HANDLE hNamedEvent; HANDLE hEvent[2] = { 0, 0 }; HANDLE hMutex = 0; HANDLE hSemaphore = 0; HANDLE hObjs[2]; DWORD dwThreadNum; DWORD dwSlaveThreadTid = 0; HANDLE hThread; int i, iCnt, iRet; char szTestName[128]; char szCmd[128]; char szEventName[128] = { 0 }; char szMutexName[128] = { 0 }; char szSemName[128] = { 0 }; WCHAR wszEventName[128] = { 0 }; WCHAR wszMutexName[128] = { 0 }; WCHAR wszSemName[128] = { 0 }; BOOL bMutex = g_bMutex; BOOL bEvent = g_bEvent; BOOL bNamedEvent = g_bNamedEvent; BOOL bSemaphore = g_bSemaphore; BOOL bProcess = g_bProcess; BOOL bLocalWaitAll = g_bLocalWaitAll; BOOL bRemoteWaitAll = g_bRemoteWaitAll; int iDesiredExitCode; dwThreadNum = (DWORD)pArg; _snprintf (szTestName, 128, "Test6_%u", dwThreadNum); szTestName[127] = 0; _snprintf(szEventName, 128, "%s_Event", szTestName); szEventName[127] = 0; _snprintf(szMutexName, 128, "%s_Mutex", szTestName); szMutexName[127] = 0; _snprintf(szSemName, 128, "%s_Semaphore", szTestName); szSemName[127] = 0; iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128); iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128); iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128); if (0 == iRet) { Fail("[TestThread] Failed to convert strings\n"); } Trace("[TestThread] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n", szTestName, wszEventName, wszMutexName, wszSemName); hEvent[0] = CreateEventA(NULL, FALSE, FALSE, NULL); hEvent[1] = CreateEventA(NULL, FALSE, FALSE, NULL); hNamedEvent = CreateEventW(NULL, FALSE, FALSE, wszEventName); hMutex = CreateMutexW(NULL, FALSE, wszMutexName); hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName); if (NULL == hEvent[0] || NULL == hEvent[1] || NULL == hMutex || NULL == hNamedEvent || NULL == hSemaphore) { Fail("[TestThread] Failed to create objects " "[hNamedEvent=%p hMutex=%p hSemaphore=%p]\n", (VOID*)hNamedEvent, (VOID*)hMutex, (VOID*)hSemaphore); } for (iCnt=0; iCnt<iCount; iCnt++) { if (g_bRandom) { int iRnd; bMutex = 0; bEvent = 0; bNamedEvent = 0; bSemaphore = 0; bProcess = 0; bLocalWaitAll = 0; bRemoteWaitAll = 0; iRnd = rand() % 7; switch(iRnd) { case 0: bMutex = 1; break; case 1: bEvent = 1; break; case 2: bNamedEvent = 1; break; case 3: bSemaphore = 1; break; case 4: bProcess = 1; break; case 5: bLocalWaitAll = 1; break; case 6: bRemoteWaitAll = 1; break; } } if (bEvent) { Trace("======================================================================\n"); Trace("Local unnamed event test\n"); Trace("----------------------------------------\n"); hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid); if (NULL == hThread) { Fail("Failed to create thread\n"); } hObjs[0] = hEvent[0]; dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed\n"); } hObjs[0] = hThread; dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed\n"); } CloseHandle(hThread); Trace("Local unnamed event test done \n"); Trace("======================================================================\n"); } if (bMutex) { Trace("======================================================================\n"); Trace("Mutex with remote thread awakening test\n"); Trace("----------------------------------------\n"); hThread = CreateThread(NULL, 0, MutexTestThread, (PVOID)hMutex, 0, &dwSlaveThreadTid); if (NULL == hThread) { Fail("Failed to create thread\n"); } Sleep(1000); hObjs[0] = hMutex; for (i=0;i<10;i++) { dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [dwRet=%x GetLastError()=%d\n", dwRet, GetLastError()); } } hObjs[0] = hThread; dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } for (i=0;i<10;i++) { bRet = ReleaseMutex(hMutex); if (FALSE == bRet) { Fail("ReleaseMutex failed [GetLastError()=%u]\n", GetLastError()); } } CloseHandle(hThread); Trace("Mutex with remote thread awakening test done\n"); Trace("======================================================================\n"); } if (bNamedEvent) { Trace("======================================================================\n"); Trace("Named event with remote thread awakening test\n"); Trace("----------------------------------------\n"); ZeroMemory ( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory ( &pi, sizeof(pi) ); _snprintf (szCmd, 128, "child6 -event %s", szTestName); szCmd[127] = 0; bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { Fail("CreateProcess failed [GetLastError()=%u]\n", GetLastError()); } hObjs[0] = pi.hProcess; hObjs[1] = hNamedEvent; dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE); if (1 != dwRet) { Fail("WaitForMultipleObjects failed [dwRet=%u GetLastError()=%u]\n", dwRet, GetLastError()); } dwRet = WaitForSingleObject(pi.hProcess, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } Trace("Named event with remote thread awakening test done\n"); Trace("======================================================================\n"); } if (bSemaphore) { Trace("======================================================================\n"); Trace("Semaphore with remote thread awakening test\n"); Trace("----------------------------------------\n"); ZeroMemory ( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory ( &pi, sizeof(pi) ); _snprintf (szCmd, 128, "child6 -semaphore %s", szTestName); szCmd[127] = 0; bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { Fail("CreateProcessA failed [GetLastError()=%u]\n", GetLastError()); } Trace("Setting event %s\n", szEventName); bRet = SetEvent(hNamedEvent); if (FALSE == bRet) { Fail("[child] SetEvent failed [GetLastError()=%u]\n", GetLastError()); } Trace("Going to wait on semaphore %s\n", szSemName); hObjs[0] = pi.hProcess; hObjs[0] = hEvent[0]; hObjs[1] = hSemaphore; for (i=0;i<10;i++) { dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE); if (1 != dwRet) { Trace("WaitForMultipleObjects failed [tid=%u dwRet=%u GetLastError()=%u]\n", GetCurrentThreadId(), dwRet, GetLastError()); DebugBreak(); } } dwRet = WaitForSingleObject(pi.hProcess, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } Trace("Semaphore with remote thread awakening test done\n"); Trace("======================================================================\n"); } if (bProcess) { DWORD dwExitCode; Trace("======================================================================\n"); Trace("Process wait test\n"); Trace("----------------------------------------\n"); iDesiredExitCode = rand() % 0xFF; ZeroMemory ( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory ( &pi, sizeof(pi) ); _snprintf (szCmd, 128, "child6 -mutex %s -exitcode %d", szTestName, iDesiredExitCode); szCmd[127] = 0; bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { Fail("CreateProcess failed [GetLastError()=%u]\n", GetLastError()); } Trace("Going to wait on event %s\n", szEventName); dwRet = WaitForSingleObject(hNamedEvent, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } hObjs[0] = hEvent[0]; // dummy, this is a local event hObjs[1] = hMutex; dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } if (1 == dwRet || (1 + WAIT_ABANDONED_0) == dwRet) { bRet = ReleaseMutex(hMutex); if (FALSE == bRet) { Fail("ReleaseMutex failed [GetLastError()=%u]\n", GetLastError()); } } dwRet = WaitForSingleObject(pi.hProcess, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } if (!GetExitCodeProcess(pi.hProcess, &dwExitCode)) { Trace("GetExitCodeProcess call failed LastError:(%u)\n", GetLastError()); dwExitCode = FAIL; } if (iDesiredExitCode != dwExitCode) { Fail("Wrong return code: %u [%d]\n", dwExitCode, iDesiredExitCode); } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); Trace("Process wait test done\n"); Trace("======================================================================\n"); } if (bLocalWaitAll) { Trace("======================================================================\n"); Trace("WaitAll with local thread awakening test\n"); Trace("----------------------------------------\n"); hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid); if (NULL == hThread) { Fail("CreateThread failed [GetLastError()=%u]\n", GetLastError()); } dwRet = WaitForMultipleObjects(2, hEvent, TRUE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } hObjs[0] = hThread; dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } CloseHandle(hThread); Trace("WaitAll with local thread awakening test done\n"); Trace("======================================================================\n"); } if (bRemoteWaitAll) { Trace("======================================================================\n"); Trace("WaitAll with remote thread awakening test\n"); Trace("----------------------------------------\n"); ZeroMemory ( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory ( &pi, sizeof(pi) ); _snprintf (szCmd, 128, "child6 -mutex_and_named_event %s", szTestName); szCmd[127] = 0; bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { Fail("CreateProcess failed [GetLastError()=%u]\n", GetLastError()); } Sleep(1000); hObjs[0] = hMutex; hObjs[1] = hNamedEvent; dwRet = WaitForMultipleObjects(2, hObjs, TRUE, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } bRet = ReleaseMutex(hMutex); if (FALSE == bRet) { Fail("ReleaseMutex failed [GetLastError()=%u]\n", GetLastError()); } dwRet = WaitForSingleObject(pi.hProcess, INFINITE); if (WAIT_FAILED == dwRet) { Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); Trace("WaitAll with remote thread awakening test done\n"); Trace("======================================================================\n"); } } return 0; }
int __cdecl main(int argc, char **argv) { int i, iRet; BOOL bRet; BOOL bNamedEvent = 0; BOOL bMutex = 0; BOOL bMutexAndNamedEvent = 0; BOOL bSemaphore = 0; DWORD dwRet; HANDLE hNamedEvent; HANDLE hMutex; char szTestName[256]; WCHAR wszTestName[256] = { 0 }; char szEventName[128] = { 0 }; char szMutexName[128] = { 0 }; char szSemName[128] = { 0 }; WCHAR wszEventName[128]; WCHAR wszMutexName[128]; WCHAR wszSemName[128]; DWORD iExitCode = 0; HANDLE hSemaphore; if(0 != (PAL_Initialize(argc, argv))) { return ( FAIL ); } Trace("[child] Starting\n"); for (i=1; i<argc; i++) { if (0 == strcmp(argv[i],"-event")) { bNamedEvent = 1; } else if (0 == strcmp(argv[i],"-mutex")) { bMutex = 1; } else if (0 == strcmp(argv[i],"-mutex_and_named_event")) { bMutexAndNamedEvent = 1; } else if (0 == strcmp(argv[i],"-semaphore")) { bSemaphore = 1; } else if (0 == strcmp(argv[i],"-exitcode") && i < argc-1 ) { i++; iExitCode = atoi(argv[i]); Trace("[child] My exit code is %d\n", iExitCode); } else if ('-' != *argv[i]) { strncpy(szTestName, argv[i], 256); szTestName[255] = 0; iRet = MultiByteToWideChar(CP_ACP, 0, szTestName, strlen(szTestName)+1, wszTestName, 256); if (0 == iRet) { Fail("Failed to convert test string\n"); } } } sprintf_s(szEventName, 128, "%s_Event", szTestName); szEventName[127] = 0; sprintf_s(szMutexName, 128, "%s_Mutex", szTestName); szMutexName[127] = 0; sprintf_s(szSemName, 128, "%s_Semaphore", szTestName); szSemName[127] = 0; iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128); iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128); iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128); if (0 == iRet) { Fail("[child] Failed to convert strings\n"); } Trace("[child] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n", szTestName, wszEventName, wszMutexName, wszSemName); hNamedEvent = OpenEventW(0, FALSE, wszEventName); if (NULL == hNamedEvent) { Fail("[child] OpenEventW failed [szEventName=%s GetLastError()=%u]\n", szEventName, GetLastError()); } hMutex = OpenMutexW(0, FALSE, wszMutexName); if (NULL == hMutex) { Fail("[child] OpenMutexW failed [GetLastError()=%u]\n", GetLastError()); } hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName); if (NULL == hSemaphore) { Fail("[child] CreateSemaphore failed [GetLastError()=%u]\n", GetLastError()); } if (bMutex) { Trace("[child] Going to wait on mutex %s\n", szMutexName); dwRet = WaitForSingleObject(hMutex, INFINITE); if (WAIT_FAILED == dwRet) { Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } Trace("[child] Setting event %s\n", szEventName); bRet = SetEvent(hNamedEvent); if (FALSE == bRet) { Fail("[child] SetEvent failed [GetLastError()=%u]\n", GetLastError()); } // mutex will be abandoned } else if (bMutexAndNamedEvent) { dwRet = WaitForSingleObject(hMutex, INFINITE); if (WAIT_FAILED == dwRet) { Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } Sleep(2000); bRet = ReleaseMutex(hMutex); if (FALSE == bRet) { Fail("[child] ReleaseMutex failed [GetLastError()=%u]\n", GetLastError()); } Sleep(1000); bRet = SetEvent(hNamedEvent); if (FALSE == bRet) { Fail("[child] SetEvent failed [GetLastError()=%u]\n", GetLastError()); } } else if (bSemaphore) { LONG lPrevCount = 42; Trace("[child] Going to wait on event %s\n", szEventName); dwRet = WaitForSingleObject(hNamedEvent, INFINITE); if (WAIT_FAILED == dwRet) { Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n", GetLastError()); } Trace("[child] Releasing semaphore %s\n", szSemName); bRet = ReleaseSemaphore(hSemaphore, 10, &lPrevCount); if (FALSE == bRet) { Fail("ReleaseMutex failed [GetLastError()=%u]\n", GetLastError()); } if (0 != lPrevCount) { Fail("Previous count from semaphore=%d, expected 0\n", lPrevCount); } } else if (bNamedEvent) { Sleep(1000); bRet = SetEvent(hNamedEvent); if (FALSE == bRet) { Fail("[child] SetEvent failed [GetLastError()=%u]\n", GetLastError()); } } Sleep(1000); Trace("[child] Done\n"); PAL_TerminateEx(iExitCode); return iExitCode; }
Semaphore::Semaphore() : m_nCount(1) { m_hSemaphore = CreateSemaphoreW(NULL, m_nCount, m_nCount, NULL); }
int __cdecl main (int argc, char **argv) { BufferStructure Buffer, *pBuffer; pBuffer = &Buffer; if(0 != (PAL_Initialize(argc, argv))) { return ( FAIL ); } /* * Create Semaphores */ hSemaphoreM = CreateSemaphoreW ( NULL, 1, 1, NULL); if ( NULL == hSemaphoreM ) { Fail ( "hSemaphoreM = CreateSemaphoreW () - returned NULL\n" "Failing Test.\nGetLastError returned %d\n", GetLastError()); } hSemaphoreE = CreateSemaphoreW ( NULL, _BUF_SIZE , _BUF_SIZE , NULL); if ( NULL == hSemaphoreE ) { Fail ( "hSemaphoreE = CreateSemaphoreW () - returned NULL\n" "Failing Test.\nGetLastError returned %d\n", GetLastError()); } hSemaphoreF = CreateSemaphoreW ( NULL, 0, _BUF_SIZE , NULL); if ( NULL == hSemaphoreF ) { Fail ( "hSemaphoreF = CreateSemaphoreW () - returned NULL\n" "Failing Test.\nGetLastError returned %d\n", GetLastError()); } /* * Initialize Buffer */ pBuffer->writeIndex = pBuffer->readIndex = 0; /* * Create Consumer */ hThread = CreateThread( NULL, 0, consumer, &Buffer, 0, &dwThreadId); if ( NULL == hThread ) { Fail ( "CreateThread() returned NULL. Failing test.\n" "GetLastError returned %d\n", GetLastError()); } /* * Start producing */ producer(pBuffer); /* * Wait for consumer to complete */ WaitForSingleObject (hThread, INFINITE); /* * Compare items produced vs. items consumed */ if ( 0 != strncmp (producerItems, consumerItems, PRODUCTION_TOTAL) ) { Fail("The producerItems string %s\n and the consumerItems string " "%s\ndo not match. This could be a problem with the strncmp()" " function\n FailingTest\nGetLastError() returned %d\n", producerItems, consumerItems, GetLastError()); } Trace ("producerItems and consumerItems arrays match. All %d\nitems " "were produced and consumed in order.\nTest passed.\n", PRODUCTION_TOTAL); PAL_Terminate(); return ( PASS ); }
static void test_tp_wait(void) { TP_CALLBACK_ENVIRON environment; TP_WAIT *wait1, *wait2; struct wait_info info; HANDLE semaphores[2]; LARGE_INTEGER when; NTSTATUS status; TP_POOL *pool; DWORD result; semaphores[0] = CreateSemaphoreW(NULL, 0, 2, NULL); ok(semaphores[0] != NULL, "failed to create semaphore\n"); semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL); ok(semaphores[1] != NULL, "failed to create semaphore\n"); info.semaphore = semaphores[0]; /* allocate new threadpool */ pool = NULL; status = pTpAllocPool(&pool, NULL); ok(!status, "TpAllocPool failed with status %x\n", status); ok(pool != NULL, "expected pool != NULL\n"); /* allocate new wait items */ memset(&environment, 0, sizeof(environment)); environment.Version = 1; environment.Pool = pool; wait1 = NULL; status = pTpAllocWait(&wait1, wait_cb, &info, &environment); ok(!status, "TpAllocWait failed with status %x\n", status); ok(wait1 != NULL, "expected wait1 != NULL\n"); wait2 = NULL; status = pTpAllocWait(&wait2, wait_cb, &info, &environment); ok(!status, "TpAllocWait failed with status %x\n", status); ok(wait2 != NULL, "expected wait2 != NULL\n"); /* infinite timeout, signal the semaphore immediately */ info.userdata = 0; pTpSetWait(wait1, semaphores[1], NULL); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* relative timeout, no event */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* repeat test with call to TpWaitForWait(..., TRUE) */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); pTpWaitForWait(wait1, TRUE); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */, "WaitForSingleObject returned %u\n", result); if (result == WAIT_OBJECT_0) ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); else ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* relative timeout, with event */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* repeat test with call to TpWaitForWait(..., TRUE) */ info.userdata = 0; when.QuadPart = (ULONGLONG)200 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); pTpWaitForWait(wait1, TRUE); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0 || broken(result == WAIT_TIMEOUT) /* Win 8 */, "WaitForSingleObject returned %u\n", result); if (result == WAIT_OBJECT_0) { ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); } else { ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); } /* absolute timeout, no event */ info.userdata = 0; NtQuerySystemTime( &when ); when.QuadPart += (ULONGLONG)200 * 10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[0], 200); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* absolute timeout, with event */ info.userdata = 0; NtQuerySystemTime( &when ); when.QuadPart += (ULONGLONG)200 * 10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* test timeout of zero */ info.userdata = 0; when.QuadPart = 0; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* cancel a pending wait */ info.userdata = 0; when.QuadPart = (ULONGLONG)250 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); pTpSetWait(wait1, NULL, (void *)0xdeadbeef); Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0, "expected info.userdata = 0, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); /* test with INVALID_HANDLE_VALUE */ info.userdata = 0; when.QuadPart = 0; pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); /* cancel a pending wait with INVALID_HANDLE_VALUE */ info.userdata = 0; when.QuadPart = (ULONGLONG)250 * -10000; pTpSetWait(wait1, semaphores[1], &when); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); when.QuadPart = 0; pTpSetWait(wait1, INVALID_HANDLE_VALUE, &when); Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 0x10000, "expected info.userdata = 0x10000, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); CloseHandle(semaphores[1]); semaphores[1] = CreateSemaphoreW(NULL, 0, 2, NULL); ok(semaphores[1] != NULL, "failed to create semaphore\n"); /* add two wait objects with the same semaphore */ info.userdata = 0; pTpSetWait(wait1, semaphores[1], NULL); pTpSetWait(wait2, semaphores[1], NULL); Sleep(50); ReleaseSemaphore(semaphores[1], 1, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 1, "expected info.userdata = 1, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* repeat test above with release count 2 */ info.userdata = 0; pTpSetWait(wait1, semaphores[1], NULL); pTpSetWait(wait2, semaphores[1], NULL); Sleep(50); result = ReleaseSemaphore(semaphores[1], 2, NULL); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); result = WaitForSingleObject(semaphores[0], 100); ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); ok(info.userdata == 2, "expected info.userdata = 2, got %u\n", info.userdata); result = WaitForSingleObject(semaphores[1], 0); ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); /* cleanup */ pTpReleaseWait(wait1); pTpReleaseWait(wait2); pTpReleasePool(pool); CloseHandle(semaphores[0]); CloseHandle(semaphores[1]); }