Esempio n. 1
0
	bool WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort, DWORD timeout /*must not be INFINITE*/) {
		PFC_ASSERT( timeout != INFINITE );
		const DWORD entry = GetTickCount();
		const HANDLE handles[2] = {ev, abort.get_abort_event()};
		for(;;) {
			const DWORD done = GetTickCount() - entry;
			if (done >= timeout) return false;
			SetLastError(0);
			const DWORD status = MsgWaitForMultipleObjects(2, handles, FALSE, timeout - done, QS_ALLINPUT);
			switch(status) {
				case WAIT_TIMEOUT:
					return false;
				case WAIT_OBJECT_0:
					return true;
				case WAIT_OBJECT_0 + 1:
					throw exception_aborted();
				case WAIT_OBJECT_0 + 2:
					ProcessPendingMessages();
					break;
				case WAIT_FAILED:
					WIN32_OP_FAIL();
				default:
					uBugCheck();
			}
		}
	}
	void writeOverlappedPass(HANDLE handle, HANDLE myEvent, t_filesize position, const void * in,DWORD inBytes, abort_callback & abort) {
		abort.check();
		if (inBytes == 0) return;
		OVERLAPPED ol = {};
		fillOverlapped(ol, myEvent, position);
		ResetEvent(myEvent);
		DWORD bytesWritten;
		SetLastError(NO_ERROR);
		if (WriteFile( handle, in, inBytes, &bytesWritten, &ol)) {
			// succeeded already?
			if (bytesWritten != inBytes) throw exception_io();
			return;
		}
		
		{
			const DWORD code = GetLastError();
			if (code != ERROR_IO_PENDING) exception_io_from_win32(code);
		}
		const HANDLE handles[] = {myEvent, abort.get_abort_event()};
		SetLastError(NO_ERROR);
		DWORD state = WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE);
		if (state == WAIT_OBJECT_0) {
			try {
				WIN32_IO_OP( GetOverlappedResult(handle,&ol,&bytesWritten,TRUE) );
			} catch(...) {
				CancelIo(handle);
				throw;
			}
			if (bytesWritten != inBytes) throw exception_io();
			return;
		}
		CancelIo(handle);
		throw exception_aborted();
	}
Esempio n. 3
0
	t_size MultiWaitAbortable_MsgLoop(const HANDLE * ev, t_size evCount, abort_callback & abort) {
		pfc::array_t<HANDLE> handles; handles.set_size(evCount + 1);
		handles[0] = abort.get_abort_event();
		pfc::memcpy_t(handles.get_ptr() + 1, ev, evCount);
		for(;;) {
			SetLastError(0);
			const DWORD status = MsgWaitForMultipleObjects(handles.get_count(), handles.get_ptr(), FALSE, INFINITE, QS_ALLINPUT);
			switch(status) {
				case WAIT_TIMEOUT:
					PFC_ASSERT(!"How did we get here?");
					uBugCheck();
				case WAIT_OBJECT_0:
					throw exception_aborted();
				case WAIT_FAILED:
					WIN32_OP_FAIL();
				default:
					{
						t_size index = (t_size)(status - (WAIT_OBJECT_0 + 1));
						if (index == evCount) {
							ProcessPendingMessages();
						} else if (index < evCount) {
							return index;
						} else {
							uBugCheck();
						}
					}
			}
		}
	}
Esempio n. 4
0
mutexScope::mutexScope(HANDLE hMutex_, abort_callback & abort) : hMutex(hMutex_) {
	HANDLE h[2] = {hMutex, abort.get_abort_event()};
	switch( WaitForMultipleObjects(2, h, FALSE, INFINITE) ) {
	case WAIT_OBJECT_0:
		break; // and enter
	case WAIT_OBJECT_0+1:
		throw exception_aborted();
	default:
		uBugCheck();			
	}
}
Esempio n. 5
0
void CMutex::AcquireByHandle( HANDLE hMutex, abort_callback & aborter ) {
	SetLastError(0);
	HANDLE hWait[2] = {hMutex, aborter.get_abort_event()};
	switch(WaitForMultipleObjects( 2, hWait, FALSE, INFINITE ) ) {
	case WAIT_FAILED:
		WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
	case WAIT_OBJECT_0:
		return;
	case WAIT_OBJECT_0 + 1:
		PFC_ASSERT( aborter.is_aborting() );
		throw exception_aborted();
	default:
		uBugCheck();
	}
}
	HANDLE createFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile, abort_callback & abort) {
		abort.check();
		
		return CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

		// CancelSynchronousIo() doesn't f*****g work. Useless.
#if 0
		pCancelSynchronousIo_t pCancelSynchronousIo = (pCancelSynchronousIo_t) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelSynchronousIo");
		if (pCancelSynchronousIo == NULL) {
#ifdef _DEBUG
			uDebugLog() << "Async CreateFile unavailable - using regular";
#endif
			return CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
		} else {
#ifdef _DEBUG
			uDebugLog() << "Starting async CreateFile...";
			pfc::hires_timer t; t.start();
#endif
			createFileData_t data = {lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, NULL, 0};
			HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, createFileProc, &data, 0, NULL);
			HANDLE waitHandles[2] = {hThread, abort.get_abort_event()};
			switch(WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE)) {
			case WAIT_OBJECT_0: // succeeded
				break;
			case WAIT_OBJECT_0 + 1: // abort
#ifdef _DEBUG
				uDebugLog() << "Aborting async CreateFile...";
#endif
				pCancelSynchronousIo(hThread);
				WaitForSingleObject(hThread, INFINITE);
				break;
			default:
				uBugCheck();
			}
			CloseHandle(hThread);
			SetLastError(data.dwErrorCode);
#ifdef _DEBUG
			uDebugLog() << "Async CreateFile completed in " << pfc::format_time_ex(t.query(), 6) << ", status: " << (uint32_t) data.dwErrorCode;
#endif
			if (abort.is_aborting()) {
				if (data.hResult != INVALID_HANDLE_VALUE) CloseHandle(data.hResult);
				throw exception_aborted();
			}
			return data.hResult;
		}
#endif
	}
Esempio n. 7
0
	bool WaitAbortable(HANDLE ev, abort_callback & abort, DWORD timeout) {
		const HANDLE handles[2] = {ev, abort.get_abort_event()};
		SetLastError(0);
		const DWORD status = WaitForMultipleObjects(2, handles, FALSE, timeout);
		switch(status) {
			case WAIT_TIMEOUT:
				PFC_ASSERT( timeout != INFINITE );
				return false;
			case WAIT_OBJECT_0:
				return true;
			case WAIT_OBJECT_0 + 1:
				throw exception_aborted();
			case WAIT_FAILED:
				WIN32_OP_FAIL();
			default:
				uBugCheck();
		}
	}
	DWORD readOverlappedPass(HANDLE handle, HANDLE myEvent, t_filesize position, void * out, DWORD outBytes, abort_callback & abort) {
		abort.check();
		if (outBytes == 0) return 0;
		OVERLAPPED ol = {};
		fillOverlapped(ol, myEvent, position);
		ResetEvent(myEvent);
		DWORD bytesDone;
		SetLastError(NO_ERROR);
		if (ReadFile( handle, out, outBytes, &bytesDone, &ol)) {
			// succeeded already?
			return bytesDone;
		}

		{
			const DWORD code = GetLastError();
			switch(code) {
			case ERROR_HANDLE_EOF:
			case ERROR_BROKEN_PIPE:
				return 0;
			case ERROR_IO_PENDING:
				break; // continue
			default:
				exception_io_from_win32(code);
			};
		}

		const HANDLE handles[] = {myEvent, abort.get_abort_event()};
		SetLastError(NO_ERROR);
		DWORD state = WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE);
		if (state == WAIT_OBJECT_0) {
			SetLastError(NO_ERROR);
			if (!GetOverlappedResult(handle,&ol,&bytesDone,TRUE)) {
				const DWORD code = GetLastError();
				if (code == ERROR_HANDLE_EOF || code == ERROR_BROKEN_PIPE) bytesDone = 0;
				else {
					CancelIo(handle);
					exception_io_from_win32(code);
				}
			}
			return bytesDone;
		}
		CancelIo(handle);
		throw exception_aborted();
	}
Esempio n. 9
0
	void SleepAbortable_MsgLoop(abort_callback & abort, DWORD timeout /*must not be INFINITE*/) {
		PFC_ASSERT( timeout != INFINITE );
		const DWORD entry = GetTickCount();
		const HANDLE handles[1] = {abort.get_abort_event()};
		for(;;) {
			const DWORD done = GetTickCount() - entry;
			if (done >= timeout) return;
			SetLastError(0);
			const DWORD status = MsgWaitForMultipleObjects(1, handles, FALSE, timeout - done, QS_ALLINPUT);
			switch(status) {
				case WAIT_TIMEOUT:
					return;
				case WAIT_OBJECT_0:
					throw exception_aborted();
				case WAIT_OBJECT_0 + 1:
					ProcessPendingMessages();
				default:
					throw exception_win32(GetLastError());
			}
		}
	}
Esempio n. 10
0
	void WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort) {
		const HANDLE handles[2] = {ev, abort.get_abort_event()};
		for(;;) {
			SetLastError(0);
			const DWORD status = MsgWaitForMultipleObjects(2, handles, FALSE, INFINITE, QS_ALLINPUT);
			switch(status) {
				case WAIT_TIMEOUT:
					PFC_ASSERT(!"How did we get here?");
					uBugCheck();
				case WAIT_OBJECT_0:
					return;
				case WAIT_OBJECT_0 + 1:
					throw exception_aborted();
				case WAIT_OBJECT_0 + 2:
					ProcessPendingMessages();
					break;
				case WAIT_FAILED:
					WIN32_OP_FAIL();
				default:
					uBugCheck();
			}
		}
	}