static DWORD WINAPI start_monitoring(LPVOID param) { WDM_PMonitor monitor; WDM_PEntry curr_entry; monitor = (WDM_PMonitor)param; curr_entry = monitor->head; WDM_DEBUG("Starting the monitoring thread!"); while(curr_entry != NULL) { if ( ! register_monitoring_entry(curr_entry) ) { WDM_PQueueItem error_item; int directory_bytes; LPSTR multibyte_directory; directory_bytes = WideCharToMultiByte(CP_UTF8, 0, curr_entry->user_data->dir, -1, NULL, 0, NULL, NULL); multibyte_directory = ALLOCA_N(CHAR, directory_bytes); WideCharToMultiByte(CP_UTF8, 0, curr_entry->user_data->dir, -1, multibyte_directory, directory_bytes, NULL, NULL); error_item = wdm_queue_item_new(WDM_QUEUE_ITEM_TYPE_ERROR); error_item->error = wdm_queue_item_error_new( eWDM_UnwatchableDirectoryError, "Can't watch directory: '%s'!", multibyte_directory ); wdm_queue_enqueue(monitor->changes, error_item); SetEvent(monitor->process_event); } curr_entry = curr_entry->next; } while(monitor->running) { // TODO: Is this the best way to do it? if ( WaitForSingleObjectEx(monitor->stop_event, INFINITE, TRUE) == WAIT_OBJECT_0) { WDM_DEBUG("Exiting the monitoring thread!"); ExitThread(0); } } return 0; }
void APIThreadStress::SyncThreadStress() { APIThreadStress *pThis = (APIThreadStress *) ClrFlsGetValue(TlsIdx_StressThread); if (pThis != NULL) { LOG((LF_SYNC, LL_INFO1000, "Syncing stress operation on thread %d\n", GetCurrentThreadId())); ::ResetEvent(pThis->m_syncEvent); if (InterlockedDecrement(&pThis->m_runCount) == 0) ::SetEvent(pThis->m_syncEvent); else WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE); InterlockedIncrement(&pThis->m_runCount); LOG((LF_SYNC, LL_INFO1000, "Resuming stress operation on thread %d\n", GetCurrentThreadId())); } }
DWORD ipcSendRequest(HANDLE hSignal, HANDLE hWaitFor, THeaderIPC *pipch, DWORD dwTimeoutMsecs) { // signal ST to work SetEvent(hSignal); // wait for reply, it should open a handle to hWaitFor... while (true) { switch ( WaitForSingleObjectEx(hWaitFor, dwTimeoutMsecs, true)) { case WAIT_OBJECT_0: return pipch->fRequests; case WAIT_IO_COMPLETION: // APC call... break; default: return REPLY_FAIL; } } }
ssize_t win32_fifo_read(void *buf, size_t nbyte) { int check; DWORD readbuff; DWORD available; debug1("Reading pipe handle %p", fifohandle); if (!fifohandle) return 0; available = win32_fifo_read_peek(NULL); if (!available) return 0; /* This looks more like a hack than a proper check */ readbuff = (nbyte > available) ? available : nbyte; debug("Starting ReadFileEx"); check = ReadFileEx(fifohandle,buf,readbuff,&ov1,&ReadComplete); WaitForSingleObjectEx(fifohandle,INFINITE,TRUE); debug1("Read %ld bytes from pipe", readbuff); return (!check) ? 0 : readbuff; }
extern "C" int __declspec(dllexport) Unload(void) { WaitForSingleObjectEx(hConnectionCheckThread, INFINITE, FALSE); if (hConnectionCheckThread )CloseHandle(hConnectionCheckThread); if (hCheckEvent)DestroyHookableEvent(hCheckEvent); if (hOptInit) UnhookEvent(hOptInit); if (hCheckHook)UnhookEvent(hCheckHook); if (hHookModulesLoaded)UnhookEvent(hHookModulesLoaded); if (hHookPreShutdown)UnhookEvent(hHookPreShutdown); if (killCheckThreadEvent) CloseHandle(killCheckThreadEvent); //if (hCurrentEditMutex) CloseHandle(hCurrentEditMutex); if (hExceptionsMutex) CloseHandle(hExceptionsMutex); #ifdef _DEBUG _OutputDebugString(_T("Unloaded")); #endif return 0; }
DWORD mono_win32_wait_for_single_object_ex (HANDLE handle, DWORD timeout, BOOL alertable) { DWORD result = WAIT_FAILED; MonoThreadInfo * const info = alertable ? mono_thread_info_current_unchecked () : NULL; if (info) enter_alertable_wait (info); result = WaitForSingleObjectEx (handle, timeout, alertable); // NOTE, leave_alertable_wait should not affect GetLastError but // if changed, GetLastError needs to be preserved and reset before returning. if (alertable && info) { leave_alertable_wait (info); } return result; }
// Prepare to render the next frame. void D3D12PredicationQueries::MoveToNextFrame() { // Schedule a Signal command in the queue. const UINT64 currentFenceValue = m_fenceValues[m_frameIndex]; ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue)); // Update the frame index. m_frameIndex = m_swapChain->GetCurrentBackBufferIndex(); // If the next frame is not ready to be rendered yet, wait until it is ready. if (m_fence->GetCompletedValue() < m_fenceValues[m_frameIndex]) { ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_frameIndex], m_fenceEvent)); WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE); } // Set the fence value for the next frame. m_fenceValues[m_frameIndex] = currentFenceValue + 1; }
// Wait on the condition variable. In the XP implementation using only a Windows event // we can't guarantee that we'll ever actually receive the notification signal, so we // must use a non-infinite timeout. This is not optimal: we may wake up early if the // initializer is long-running, or we may miss the signal and not wake up until the // timeout expires. The signal may be missed because the sleeping threads may be // stolen by the kernel to service an APC, or due to the race condition between the // unlock call and the WaitForSingleObject call. extern "C" bool __cdecl _Init_thread_wait(DWORD const timeout) { #if _CRT_NTDDI_MIN < NTDDI_VISTA if (!__scrt_is_event_api_used(_Tss_event)) { return __crt_fast_decode_pointer(encoded_sleep_condition_variable_cs)(&_Tss_cv, &_Tss_mutex, timeout) != FALSE; } else { _ASSERT(timeout != INFINITE); _Init_thread_unlock(); HRESULT res = WaitForSingleObjectEx(_Tss_event, timeout, FALSE); _Init_thread_lock(); return (res == WAIT_OBJECT_0); } #else return SleepConditionVariableCS(&_Tss_cv, &_Tss_mutex, timeout) != FALSE; #endif }
int mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable) { gboolean res; while ((res = WaitForSingleObjectEx (*sem, timeout_ms, alertable)) == WAIT_IO_COMPLETION) { if (alertable) { errno = EINTR; return -1; } } switch (res) { case WAIT_OBJECT_0: return 0; // WAIT_TIMEOUT and WAIT_FAILED default: return -1; } }
/* msgloop_stop: * msgloop_stop should be called from miranda's gui thread * to stop the qcs_msg loop. */ void msgloop_stop() { struct msgloop_message_list_entry * entry; ASSERT_RETURNIFFAIL(!s_fStopLoop); /* stop packet scheduler timer */ KillTimer(NULL, s_outputTimer); s_outputTimer = 0; /* signal the thread to stop */ s_hStopWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); QueueUserAPC(msgloop_apc_stop, s_hLoopThread, (ULONG_PTR)NULL); /* wait for the thread to stop * and handle all the queued APCs */ while(WaitForSingleObjectEx(s_hStopWaitEvent, 10, TRUE) == WAIT_IO_COMPLETION) /* do nothing */ ; CloseHandle(s_hStopWaitEvent); CloseHandle(s_hMainThread); /* do cleanup */ s_fLoopStarted = FALSE; /* send all the queued packets that didn't get sent * by packet scheduler in msgloop_packet_output_timer_c() */ entry = s_outputListTail; while(entry) { struct msgloop_message_list_entry * next = entry->next; vqp_link_send(entry->msg); vqp_msg_free(entry->msg); free(entry); entry = next; } s_outputListTail = NULL; s_outputListHead = NULL; }
bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout) { WSAEVENT wsa_event = WSACreateEvent(); if (wsa_event == WSA_INVALID_EVENT) { return FALSE; } if (WSAEventSelect(sock, wsa_event, FD_CONNECT) == SOCKET_ERROR) { WSACloseEvent(wsa_event); return FALSE; } /* Connect (non-blocking). */ struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htonl(remote_addr); sock_addr.sin_port = htons(remote_port); if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) { if (WSAGetLastError() != WSAEWOULDBLOCK) { WSACloseEvent(wsa_event); return FALSE; } } /* Wait for connect to complete (both success and failure will signal). */ DWORD ret = WaitForSingleObjectEx(wsa_event, (DWORD)timeout, FALSE); WSACloseEvent(wsa_event); if (ret != WAIT_OBJECT_0) { return FALSE; } /* Detect success/failure. */ int sockaddr_size = sizeof(sock_addr); if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) { return FALSE; } return TRUE; }
/** * Setup the system log to output to a given file **/ void setupsyslog(char *filename) { if(s_hLogMutex == NULL) { HANDLE tmphdl = CreateMutex(NULL,FALSE,s_mutexName); if(GetLastError() != ERROR_ALREADY_EXISTS) s_hLogMutex = tmphdl; else if(s_hLogMutex == NULL) s_hLogMutex = tmphdl; } closesyslog(); /* acquire log access */ while(WaitForSingleObjectEx(s_hLogMutex,INFINITE,FALSE) != WAIT_OBJECT_0); if( (filename != NULL) && (strlen(filename) != 0)) { s_syslogFile = fopen(filename,"a+"); } ReleaseMutex(s_hLogMutex); }
void ms_sleep(int seconds){ #ifdef WIN32 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) Sleep(seconds*1000); #else HANDLE sleepEvent = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); if (!sleepEvent) return; WaitForSingleObjectEx(sleepEvent, seconds * 1000, FALSE); #endif #else struct timespec ts,rem; int err; ts.tv_sec=seconds; ts.tv_nsec=0; do { err=nanosleep(&ts,&rem); ts=rem; }while(err==-1 && errno==EINTR); #endif }
void asCThreadReadWriteLock::AcquireExclusive() { #if defined AS_POSIX_THREADS pthread_rwlock_wrlock(&lock); #elif defined AS_WINDOWS_THREADS // Synchronize writers, so only one tries to lock out the readers EnterCriticalSection(&writeLock); // Lock all reader out from the semaphore. Do this one by one, // so the lock doesn't have to wait until there are no readers at all. // If we try to lock all at once it is quite possible the writer will // never succeed. for( asUINT n = 0; n < maxReaders; n++ ) WaitForSingleObjectEx(readLocks, INFINITE, FALSE); // Allow another writer to lock. It will only be able to // lock the readers when this writer releases them anyway. LeaveCriticalSection(&writeLock); #endif }
int vcond_wait(struct vcond* cond, struct vlock* lock) { #if defined(__WIN32__) DWORD res = 0; #endif assert(cond); assert(lock); --cond->signal_times; while (cond->signal_times < 0) { #if defined(__WIN32__) vlock_leave(lock); WaitForSingleObjectEx(cond->event, INFINITE, FALSE); vlock_enter(lock); #else pthread_cond_wait(&cond->cond, &lock->mutex); #endif } return 0; }
static pboolean pp_cond_variable_wait_xp (PCondVariable *cond, PMutex *mutex) { PCondVariableXP *cv_xp = ((PCondVariableXP *) cond->cv); DWORD wait; cv_xp->waiters_count++; p_mutex_unlock (mutex); wait = WaitForSingleObjectEx (cv_xp->waiters_sema, INFINITE, FALSE); p_mutex_lock (mutex); if (wait != WAIT_OBJECT_0) --cv_xp->waiters_count; if (wait == WAIT_FAILED) return FALSE; return wait == WAIT_OBJECT_0 ? TRUE : FALSE; }
void ms_usleep(uint64_t usec){ #ifdef WIN32 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) Sleep((DWORD)(usec/1000)); #else HANDLE sleepEvent = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); if (!sleepEvent) return; WaitForSingleObjectEx(sleepEvent, usec / 1000, FALSE); #endif #else struct timespec ts,rem; int err; ts.tv_sec=usec/1000000LL; ts.tv_nsec=(usec%1000000LL)*1000; do { err=nanosleep(&ts,&rem); ts=rem; }while(err==-1 && errno==EINTR); #endif }
DWORD WindowsFirewallNotifyThreadStartRoutine(_In_ LPVOID lpThreadParameter) { ASSERT(lpThreadParameter); UINT32 status = NO_ERROR; THREAD_DATA* pThreadData = (THREAD_DATA*)lpThreadParameter; SERVICE_NOTIFY svcNotify = {0}; HlprEventSet(pThreadData->threadStartEvent); svcNotify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; svcNotify.pfnNotifyCallback = WindowsFirewallNotification; svcNotify.pContext = pWFNotifyThread; status = HlprServiceNotificationStateChangeRegister(L"MPSSvc", &svcNotify, SERVICE_NOTIFY_RUNNING, &scmHandle, &mpsSvcHandle); HLPR_BAIL_ON_FAILURE(status); status = WaitForSingleObjectEx(mpsSvcHandle, INFINITE, TRUE); if(status != WAIT_IO_COMPLETION) { if(status == WAIT_FAILED) status = GetLastError(); HlprLogError(L"WindowsFirewallNotifyThreadStartRoutine : WaitForSingleObjectEx() [status: %#x]", status); } HLPR_BAIL_LABEL: HLPR_CLOSE_SERVICE_HANDLE(mpsSvcHandle); HLPR_CLOSE_SERVICE_HANDLE(scmHandle); return status; }
void AutoResetEvent::wait(uint timeout) { if (timeout == 0) { // if timeout is 0 then the thread's timeslice may not be given up as with normal // sleep methods - so we will check for this condition ourselves and use SleepEx // instead SleepEx(0, TRUE); return; } #ifdef _WIN32 // it's possible for WaitForSingleObjectEx to exit before the timeout and without // the signal. due to bAlertable=TRUE other events (e.g. async i/o) can cancel the // waiting period early. WaitForSingleObjectEx(m_handle, timeout, TRUE); #else pthread_mutex_lock(&m_criticalSection); // it's possible for pthread_cond_wait/timedwait to exit before the timeout and // without a signal, but there's little we can actually do to check it since we // don't usually care about the condition - if the calling thread does care then // it needs to implement it's own checks if (timeout == _infinite) { pthread_cond_wait(&m_condition, &m_criticalSection); } else { // pthread_cond_timedwait expects the timeout to be the actual time timespec time; clock_gettime(CLOCK_REALTIME, &time); time.tv_sec += timeout / 1000; time.tv_nsec += (timeout % 1000) * 1000000L; pthread_cond_timedwait(&m_condition, &m_criticalSection, &time); } pthread_mutex_unlock(&m_criticalSection); #endif }
/* Timer management thread */ static DWORD WINAPI pg_timer_thread(LPVOID param) { DWORD waittime; Assert(param == NULL); waittime = INFINITE; for (;;) { int r; r = WaitForSingleObjectEx(timerCommArea.event, waittime, FALSE); if (r == WAIT_OBJECT_0) { /* Event signalled from main thread, change the timer */ EnterCriticalSection(&timerCommArea.crit_sec); if (timerCommArea.value.it_value.tv_sec == 0 && timerCommArea.value.it_value.tv_usec == 0) waittime = INFINITE; /* Cancel the interrupt */ else waittime = timerCommArea.value.it_value.tv_usec / 10 + timerCommArea.value.it_value.tv_sec * 1000; ResetEvent(timerCommArea.event); LeaveCriticalSection(&timerCommArea.crit_sec); } else if (r == WAIT_TIMEOUT) { /* Timeout expired, signal SIGALRM and turn it off */ pg_queue_signal(SIGALRM); waittime = INFINITE; } else { /* Should never happen */ Assert(false); } } return 0; }
MonoObject * mono_thread_pool_finish (MonoAsyncResult *ares, MonoArray **out_args, MonoObject **exc) { ASyncCall *ac; HANDLE wait_event; *exc = NULL; *out_args = NULL; /* check if already finished */ mono_monitor_enter ((MonoObject *) ares); if (ares->endinvoke_called) { *exc = (MonoObject *) mono_get_exception_invalid_operation (NULL); mono_monitor_exit ((MonoObject *) ares); return NULL; } ares->endinvoke_called = 1; /* wait until we are really finished */ if (!ares->completed) { if (ares->handle == NULL) { wait_event = CreateEvent (NULL, TRUE, FALSE, NULL); g_assert(wait_event != 0); MONO_OBJECT_SETREF (ares, handle, (MonoObject *) mono_wait_handle_new (mono_object_domain (ares), wait_event)); } else { wait_event = mono_wait_handle_get_handle ((MonoWaitHandle *) ares->handle); } mono_monitor_exit ((MonoObject *) ares); WaitForSingleObjectEx (wait_event, INFINITE, TRUE); } else { mono_monitor_exit ((MonoObject *) ares); } ac = (ASyncCall *) ares->object_data; g_assert (ac != NULL); *exc = ac->msg->exc; /* FIXME: GC add write barrier */ *out_args = ac->out_args; return ac->res; }
/* Worker routine for the watch thread. */ static DWORD WINAPI watch_worker (LPVOID arg) { struct notification *dirwatch = (struct notification *)arg; BOOL bErr; DWORD _bytes = 0; DWORD status; if (dirwatch->dir) { bErr = ReadDirectoryChangesW (dirwatch->dir, dirwatch->buf, DIRWATCH_BUFFER_SIZE, dirwatch->subtree, dirwatch->filter, &_bytes, dirwatch->io_info, watch_completion); if (!bErr) { DebPrint (("ReadDirectoryChangesW: %lu\n", GetLastError ())); /* We cannot remove the dirwatch object from watch_list, because we are in a separate thread. For the same reason, we also cannot free memory consumed by the buffers allocated for the dirwatch object. So we close the directory handle, but do not free the object itself or its buffers. We also don't touch the signature. This way, remove_watch can still identify the object, remove it, and free its memory. */ CloseHandle (dirwatch->dir); dirwatch->dir = NULL; return 1; } } do { status = WaitForSingleObjectEx(dirwatch->terminate, INFINITE, TRUE); } while (status == WAIT_IO_COMPLETION); /* The thread is about to terminate, so we clean up the dir handle. */ CloseHandle (dirwatch->dir); dirwatch->dir = NULL; return 0; }
int vthread_join(struct vthread* thread, int* quit_code) { #if defined(__WIN32__) DWORD res = 0; #else int ret = 0; #endif assert(thread); assert(quit_code); #if defined(__WIN32__) res = WaitForSingleObjectEx(thread->thread, INFINITE, FALSE); if (WAIT_FAILED == res) return -1; #else ret = pthread_join(thread->thread, NULL); retE((ret < 0), -1); #endif *quit_code = thread->quit_code; return 0; }
bool AsyncFile::waitForReadyRead(int msecs) { // qDebug() << "waitForReadyRead"; DWORD dwWaitOvpOprn = WaitForSingleObjectEx(overlapped.overlapped.hEvent, msecs, true); // qDebug() << "waitForReadyRead finished" << errorMessage(dwWaitOvpOprn); switch (dwWaitOvpOprn) { case WAIT_FAILED: return false; case WAIT_OBJECT_0: return true; case WAIT_TIMEOUT: return false; } // if( m_bAborted ) // { // return FALSE; // } return true; }
DWORD __alertable_wait(HANDLE handle, uint32_t millisec) { LARGE_INTEGER eta, now; GetSystemTimeAsFileTime((FILETIME*)&eta); eta.QuadPart += (millisec * 10000UI64); for (;;) { DWORD status = WaitForSingleObjectEx(handle, millisec, TRUE); if (status != WAIT_IO_COMPLETION) return status; if (millisec != INFINITE && millisec != 0) { GetSystemTimeAsFileTime((FILETIME*)&now); LONGLONG diff = (eta.QuadPart - now.QuadPart) / 10000; if (diff < 0) // very very very very important this is < and not <=! return WAIT_TIMEOUT; millisec = (uint32_t)diff; } } }
void timerThreadProc(ScheduleQueue* scheduleQueue){ LARGE_INTEGER period = { 0, }; period.QuadPart = -160000; while (true) { WaitForSingleObjectEx(Event::newSchedule, INFINITE, TRUE); if (scheduleOver) break; while (!scheduleQueue->empty()) { HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL); TimerArg* schedulerArg = new TimerArg(); schedulerArg->timer = timer; schedulerArg->ref_count = 1; while (scheduleQueue->try_pop(schedulerArg->room_id)); // SetWaitableTimer(timer, &period, 16, timerCallback, schedulerArg, FALSE); SetWaitableTimer(timer, &period, 0, timerCallback, schedulerArg, FALSE); } } }
void WhatsAppProto::sentinelLoop(void*) { while (WaitForSingleObjectEx(update_loop_lock_, 1000, true) == WAIT_TIMEOUT) { if (m_iStatus != ID_STATUS_OFFLINE && m_pConnection != NULL && m_iDesiredStatus == m_iStatus) { // #TODO Quiet after pong or tree read? int quietInterval = difftime(time(NULL), m_tLastWriteTime); if (quietInterval >= MAX_SILENT_INTERVAL) { try { debugLogA("send ping"); m_tLastWriteTime = time(NULL); m_pConnection->sendPing(); } catch (exception &e) { debugLogA("Exception: %s", e.what()); } } } } ResetEvent(update_loop_lock_); debugLogA("Exiting sentinel loop"); }
/**@ingroup tsk_mutex_group * Lock a mutex. You must use @ref tsk_mutex_unlock to unlock the mutex. * @param handle The handle of the mutex to lock. * @retval Zero if succeed and non-zero error code otherwise. * @sa @ref tsk_mutex_unlock. */ int tsk_mutex_lock(tsk_mutex_handle_t* handle) { int ret = EINVAL; if(handle) { #if TSK_UNDER_WINDOWS # if TSK_UNDER_WINDOWS_RT if((ret = WaitForSingleObjectEx((MUTEX_T)handle, INFINITE, TRUE)) == WAIT_FAILED) # else if((ret = WaitForSingleObject((MUTEX_T)handle, INFINITE)) == WAIT_FAILED) #endif #else if((ret = pthread_mutex_lock((MUTEX_T)handle))) #endif { TSK_DEBUG_ERROR("Failed to lock the mutex: %d", ret); } } return ret; }
bool ThreadImpl::ThreadStart(void* param) { if (_hThread != NULL) return false; ThreadParams p; p.Object = this; p.Userdata = param; #ifdef CreateEventEx p.NoitfyEvent = CreateEventExW(NULL, NULL, 0, EVENT_ALL_ACCESS); #else p.NoitfyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); #endif if (p.NoitfyEvent == NULL) return false; _hThread = CreateThread(NULL, 0, &ThreadImpl::DoThreadInvoke, &p, 0, NULL); WaitForSingleObjectEx(p.NoitfyEvent, INFINITE, FALSE); CloseHandle(p.NoitfyEvent); return _hThread != NULL; }
int mmc_lock_page(mmap_cache* cache, MU32 p_offset) { OVERLAPPED lock; DWORD lock_res, bytesTransfered; memset(&lock, 0, sizeof(lock)); lock.Offset = p_offset; lock.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (LockFileEx(cache->fh, 0, 0, cache->c_page_size, 0, &lock) == 0) { _mmc_set_error(cache, GetLastError(), "LockFileEx failed"); return -1; } lock_res = WaitForSingleObjectEx(lock.hEvent, 10000, FALSE); if (lock_res != WAIT_OBJECT_0 || GetOverlappedResult(cache->fh, &lock, &bytesTransfered, FALSE) == FALSE) { CloseHandle(lock.hEvent); _mmc_set_error(cache, GetLastError(), "Overlapped Lock failed"); return -1; } return 0; }