Esempio n. 1
0
bool IIOCPEntry::TimeoutCheck (DWORDLONG dwNow, DWORDLONG dwTimeout)

//	TimeoutCheck
//
//	Check to see if we need to cancel an operation in progress.
//	NOTE: We rely on our caller to lock appropriately.
//
//	If we return TRUE, it means the caller should delete us.

	{
	if (m_dwOpStartTime == 0)
		return false;

	HANDLE hHandle = GetCompletionHandle();
	if (hHandle == INVALID_HANDLE_VALUE)
		return false;

	DWORDLONG dwElapsed = dwNow - m_dwOpStartTime;
	if (dwElapsed <= dwTimeout)
		return false;

	if (m_iCurrentOp != opNone)
		{
		::CancelIoEx(hHandle, &m_Overlapped);
		return false;
		}
	else
		return true;
	}
Esempio n. 2
0
void  CIOCP::DestroyWorker()
{
	m_HandleIndex = 0;
	
	for(  int i = 0 ; i < m_WorkerNum ; i++ )
		PostQueuedCompletionStatus( GetCompletionHandle() , 0 , WORKER_DESTROY_KEY , NULL );

	WaitForMultipleObjects( m_WorkerNum , m_hEvent , TRUE , INFINITE );
	
	for(  int i = 0 ; i < m_WorkerNum ; i++ )
		CloseHandle( m_hEvent[i] );

	return ;
}
Esempio n. 3
0
bool IIOCPEntry::BeginWrite (const CString &sData, CString *retsError)

//	BeginWrite
//
//	Overlapped write on the given handle. Returns FALSE if we get an error.

	{
	//	Must be in the proper state

	HANDLE hHandle = GetCompletionHandle();
	if (hHandle == INVALID_HANDLE_VALUE
			|| m_iCurrentOp != opNone)
		{
		if (retsError) *retsError = ERR_INVALID_STATE;
		return false;
		}

	m_iCurrentOp = opWrite;
	m_dwOpStartTime = sysGetTickCount64();

	//	If we don't have a buffer, then we're done.

	IMemoryBlock *pBuffer = GetBuffer();
	if (pBuffer == NULL)
		{
		m_iCurrentOp = opNone;
		if (retsError) *retsError = ERR_INVALID_STATE;
		return false;
		}

	//	Initialize operation

	utlMemSet(&m_Overlapped, sizeof(m_Overlapped));

	//	Let our subclasses know (this also initializes the buffer)

	OnBeginWrite(sData);

	//	Write into the buffer

	DWORD lasterror = 0;
	if (!::WriteFile(hHandle,
			pBuffer->GetPointer(),
			pBuffer->GetLength(),
			NULL,
			&m_Overlapped))
		lasterror = GetLastError();

	//	If IO is pending or we succeeded, then nothing to do--we will get an
	//	event on the completion port.

	if (lasterror == ERROR_IO_PENDING
			|| lasterror == 0)
		return true;

	//	If another error or 0 bytes read, then we fail

	else
		{
		m_iCurrentOp = opNone;

		if (retsError)
			*retsError = strPattern(ERR_FILE_ERROR, lasterror);

		return false;
		}
	}
Esempio n. 4
0
bool IIOCPEntry::BeginConnection (const CString &sAddress, DWORD dwPort, CString *retsError)

//	BeginConnection
//
//	Overlapped connection to the given address.

	{
	//	Must be in the proper state

	HANDLE hHandle = GetCompletionHandle();
	if (hHandle == INVALID_HANDLE_VALUE
			|| m_iCurrentOp != opNone)
		{
		if (retsError) *retsError = ERR_INVALID_STATE;
		return false;
		}

	m_iCurrentOp = opConnect;
	m_dwOpStartTime = sysGetTickCount64();

	//	Bind the socket before passing to ConnectEx. For some reason the API
	//	does not do its own bind (probably so you can reuse sockets).

	SOCKADDR_IN LocalAddress;
	utlMemSet(&LocalAddress, sizeof(LocalAddress), 0);
	LocalAddress.sin_family = AF_INET;
	LocalAddress.sin_addr.s_addr = INADDR_ANY;
	LocalAddress.sin_port = 0;
	if (::bind((SOCKET)hHandle, (SOCKADDR *)&LocalAddress, sizeof(LocalAddress)) != 0)
		{
		m_iCurrentOp = opNone;
		if (retsError) *retsError = ERR_CANNOT_BIND;
		return false;
		}

	//	Get the ConnectEx pointer

	GUID guidConnectEx = WSAID_CONNECTEX;
	LPFN_CONNECTEX pfnConnectEx = NULL;
	DWORD dwBytes;
	if (::WSAIoctl((SOCKET)hHandle,
			SIO_GET_EXTENSION_FUNCTION_POINTER,
			&guidConnectEx,
			sizeof(guidConnectEx),
			&pfnConnectEx,
			sizeof(pfnConnectEx),
			&dwBytes,
			NULL,
			NULL) == SOCKET_ERROR)
		{
		m_iCurrentOp = opNone;
		if (retsError) *retsError = ERR_NOT_SUPPORTED;
		return false;
		}

	//	Compose the destination address

	SOCKADDR_IN Address;
	if (!CSocket::ComposeAddress(sAddress, dwPort, &Address))
		{
		m_iCurrentOp = opNone;
		if (retsError) *retsError = strPattern(ERR_INVALID_ADDRESS, sAddress, dwPort);
		return false;
		}

	//	Initialize operation

	utlMemSet(&m_Overlapped, sizeof(m_Overlapped));

	//	Connect

	DWORD lasterror = 0;
	if (!pfnConnectEx((SOCKET)hHandle,
			(SOCKADDR *)&Address,
			sizeof(Address),
			NULL,
			0,
			NULL,
			&m_Overlapped))
		lasterror = ::WSAGetLastError();

	//	If IO is pending or we succeeded, then nothing to do--we will get an
	//	event on the completion port.

	if (lasterror == ERROR_IO_PENDING 
			|| lasterror == 0)
		return true;

	//	If another error or 0 bytes read, then we fail

	else
		{
		m_iCurrentOp = opNone;

		if (retsError)
			*retsError = strPattern(ERR_FILE_ERROR, lasterror);

		return false;
		}
	}