Skip to content

Instantly share code, notes, and snippets.

@ianfun
Created May 24, 2022 13:43
Show Gist options
  • Save ianfun/85bf3886885c840e5fe24d1e899a734a to your computer and use it in GitHub Desktop.
Save ianfun/85bf3886885c840e5fe24d1e899a734a to your computer and use it in GitHub Desktop.
IOCP readfile example
#include <Windows.h>
#include <stdio.h>
typedef struct _PER_SOCKET_CONTEXT {
OVERLAPPED ol;
char buf[100];
HANDLE hFile;
} PER_IO_CONTEXT, * PPER_IO_CONTEXT;
DWORD WINAPI Worker(LPVOID param);
int wmain()
{
HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (iocp == NULL) {
puts("****** CreateIoCompletionPort");
return 1;
}
HANDLE hFile = CreateFileW(L"main.cpp",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (hFile == NULL) {
puts("****** CreateFileW");
return 1;
}PER_IO_CONTEXT ctx{.hFile=hFile};
iocp = CreateIoCompletionPort(hFile, iocp, (ULONG_PTR)&ctx, 0);
if (iocp==NULL){
puts("****** CreateIoCompletionPort twice failed!");
}
HANDLE hThread = CreateThread(NULL, 0, Worker, iocp, 0, NULL);
if (hThread == NULL) {
puts("****** CreateThread");
return 1;
}
if (ReadFile(hFile, ctx.buf, sizeof(ctx.buf), NULL, &ctx.ol)){
puts("****** ReadFile failed");
}
else {
WaitForSingleObject(hThread, INFINITE);
}
CloseHandle(iocp);
}
DWORD WINAPI Worker(LPVOID param) {
DWORD dwIoSize = 0;
LPOVERLAPPED ol;
PPER_IO_CONTEXT ctx;
for(;;){
BOOL bSuccess = GetQueuedCompletionStatus((HANDLE)param, &dwIoSize,
(PDWORD_PTR)&ctx,
&ol,
INFINITE);
if (ctx == NULL) {
puts("****** ctx is NULL, maybe you call PostQueuedCompletionStatus?");
break;
}
if (bSuccess==FALSE || dwIoSize == 0) {
if (GetLastError()==ERROR_HANDLE_EOF){
puts("\n****** EOF reached, stop");
}else{
printf("****** Unexpect Error GetLastError=%d(0x%x): Worker is exiting...\n", GetLastError(), GetLastError());
}
CloseHandle(ctx->hFile);
break;
}
fwrite(ctx->buf, dwIoSize, 1, stdout);
ctx->ol.Offset += dwIoSize;
if (ReadFile(ctx->hFile, ctx->buf, sizeof(ctx->buf), NULL, &ctx->ol)){
puts("****** ReadFile failed");
}
}
return 0;
}
@ianfun
Copy link
Author

ianfun commented May 25, 2022

ReadFile returns FALSE and ERROR_IO_PENDING=GetLastError() if asynchronously

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment