This is an example source for reading files using iocp.
It should be returned immediately because it makes an asynchronous call when calling ReadFile, which seems to work synchronously.
What is the problem?
he test environment is visual studio 2017 enterprise, windwos 10, The windows sdk version is 10.0.17763.0.
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
const int BUFFERSIZE = 1024 * 1024 * 400;
BYTE ReadBuffer[BUFFERSIZE] = { 0 };
DWORD WINAPI WaitQueue(LPVOID lpParam)
{
auto hIocp = (HANDLE)lpParam;
// WAIT COMPLETION QUEUE
DWORD numberOfBytes;
ULONG_PTR val;
LPOVERLAPPED ov = { 0 };
for (;;)
{
BOOL bSuccess = GetQueuedCompletionStatus(hIocp, &numberOfBytes, (PULONG_PTR)&val, &ov, INFINITE);
SYSTEMTIME dequeTime;
GetSystemTime(&dequeTime);
Sleep(1000);
printf("dequeue time %dsec %dmilli", dequeTime.wSecond, dequeTime.wMilliseconds);
}
}
DWORD WINAPI ReadFileThread(LPVOID lpParam)
{
Sleep(3000);
auto hIocp = (HANDLE)lpParam;
// CREATE FILE HANDLE
auto fileName = "e:\\test.msi";
auto hFile = CreateFile(fileName,
FILE_READ_DATA,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hFile == INVALID_HANDLE_VALUE)
{
std::wcout << L"create file fail - " << fileName << std::endl;
return 0;
}
// REGIST FILE HANDLE TO IOCP
if (hIocp != CreateIoCompletionPort(hFile, hIocp, 0, 2))
{
auto err = GetLastError();
std::cout << "add file handle fail:" << err << " - file handle:" << hIocp << std::endl;
CloseHandle(hFile);
CloseHandle(hIocp);
return 0;
}
// READ FILE
OVERLAPPED ol = { 0 };
SYSTEMTIME startTime;
GetSystemTime(&startTime);
if (FALSE == ReadFile(hFile, ReadBuffer, _countof(ReadBuffer), 0, &ol))
{
if (GetLastError() != ERROR_IO_PENDING)
{
printf("Terminal failure: Unable to read from file.\n GetLastError=%08x\n", GetLastError());
CloseHandle(hFile);
return -1;
}
}
DWORD d;
GetOverlappedResult(hFile, &ol, &d, true);
SYSTEMTIME endTime;
GetSystemTime(&endTime);
printf("start time %dsec %dmilli", startTime.wSecond, startTime.wMilliseconds);
printf("end time %dsec %dmilli", endTime.wSecond, endTime.wMilliseconds);
}
int main()
{
// CREATE ICOP
auto hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (hIocp == NULL)
{
auto err = GetLastError();
std::cout << "Create IOCP failed. error:" << err << std::endl;
return 0;
}
// CREATE READ THREAD
CreateThread(
NULL,
0,
ReadFileThread,
hIocp,
0,
nullptr
);
// CREATE WAIT DEQUEUE THREAD
CreateThread(
NULL,
0,
WaitQueue,
hIocp,
0,
nullptr
);
while (true)
{
}
return 0;
}