I am trying to do the following:
- From usermode , create a thread pool which waits for asynchronous operation(on a file) to complete.
- The threads will wait for async operation to complete using IO completion port.
However, When implementing the logic, I get a runtime error when calling CreateThreadPoolIO function. The function returns NULL and upon calling GetLastError() shows error code 87(which means parameter passed to it is incorrect).
I am not sure why it generates this error and I could not find an example on web which demonstrates what I have been trying to do. I am currently referring to MSDN documentation
to implement most of my code.
code:
VOID CALLBACK mycompletionRoutine(
PTP_CALLBACK_INSTANCE pInstance, // See "Callback Termination Actions" section
PVOID pvContext,
PVOID pOverlapped,
ULONG IoResult,
ULONG_PTR NumberOfBytesTransferred,
PTP_IO pIo)
{
std::cout << "Completion routine is invoked" << std::endl;
}
int main()
{
// Open handle to existing file in overlapped mode
HANDLE hFile = CreateFile(L"C:\\test\\text.txt", // name of the write
GENERIC_READ, // open for read
0, // do not share
NULL, // default security
OPEN_EXISTING, // ppen existing file only
FILE_FLAG_OVERLAPPED, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
std::cout << "Invalid Handle value" << std::endl;
return -1;
}
// Create a new completion port
HANDLE Iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
if (Iocp == NULL)
{
DWORD status = GetLastError();
std::cout << "Iocp is NULL" << status<< std::endl;
return -1;
}
// Associate completion port with file handle
ULONG ckey = 2;
HANDLE newIocp = CreateIoCompletionPort(hFile, Iocp, ckey, 0);
if (newIocp != Iocp)
{
DWORD status = GetLastError();
std::cout << "newIocp is NULL" << status << std::endl;
return -1;
}
// Create a thread pool object and associate it with a file handle.
PTP_IO thread_pool_obj = CreateThreadpoolIo(hFile, mycompletionRoutine, NULL, NULL);
if (thread_pool_obj == NULL)
{
DWORD status = GetLastError();
std::cout << "**Thread pool obj is NULL**" << status << std::endl;
return -1;
}
std::cout << "Program ran successfully" << std::endl;
return 0;
}