Last active
March 24, 2022 07:01
-
-
Save ssrlive/d523017dc742930dcfdb6e14920f605b to your computer and use it in GitHub Desktop.
fiber demo in windows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <tchar.h> | |
#include <stdio.h> | |
VOID __stdcall ReadFiberFunc(LPVOID lpParameter); | |
VOID __stdcall WriteFiberFunc(LPVOID lpParameter); | |
void DisplayFiberInfo(void); | |
typedef struct { | |
DWORD dwParameter; // DWORD parameter to fiber (unused) | |
DWORD dwFiberResultCode; // GetLastError() result code | |
HANDLE hFile; // handle to operate on | |
DWORD dwBytesProcessed; // number of bytes processed | |
} FIBERDATASTRUCT, *PFIBERDATASTRUCT, *LPFIBERDATASTRUCT; | |
#define RTN_OK 0 | |
#define RTN_USAGE 1 | |
#define RTN_ERROR 13 | |
#define BUFFER_SIZE 32768 // read/write buffer size | |
#define FIBER_COUNT 3 // max fibers (including primary) | |
#define PRIMARY_FIBER 0 // array index to primary fiber | |
#define READ_FIBER 1 // array index to read fiber | |
#define WRITE_FIBER 2 // array index to write fiber | |
LPVOID g_lpFiber[FIBER_COUNT]; | |
LPBYTE g_lpBuffer; | |
DWORD g_dwBytesRead; | |
int __cdecl _tmain(int argc, TCHAR *argv[]) { | |
LPFIBERDATASTRUCT fs; | |
if (argc != 3) { | |
printf("Usage: %s <SourceFile> <DestinationFile>\n", argv[0]); | |
return RTN_USAGE; | |
} | |
fs = (LPFIBERDATASTRUCT) HeapAlloc(GetProcessHeap(), 0, sizeof(FIBERDATASTRUCT) * FIBER_COUNT); | |
if (fs == NULL) { | |
printf("HeapAlloc error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
g_lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BUFFER_SIZE); | |
if (g_lpBuffer == NULL) { | |
printf("HeapAlloc error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
fs[READ_FIBER].hFile = CreateFile(argv[1], | |
GENERIC_READ, | |
FILE_SHARE_READ, | |
NULL, | |
OPEN_EXISTING, | |
FILE_FLAG_SEQUENTIAL_SCAN, | |
NULL); | |
if (fs[READ_FIBER].hFile == INVALID_HANDLE_VALUE) { | |
printf("CreateFile error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
fs[WRITE_FIBER].hFile = CreateFile(argv[2], | |
GENERIC_WRITE, | |
0, | |
NULL, | |
CREATE_NEW, | |
FILE_FLAG_SEQUENTIAL_SCAN, | |
NULL); | |
if (fs[WRITE_FIBER].hFile == INVALID_HANDLE_VALUE) { | |
printf("CreateFile error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
// | |
// Convert thread to a fiber, to allow scheduling other fibers | |
// | |
g_lpFiber[PRIMARY_FIBER]=ConvertThreadToFiber(&fs[PRIMARY_FIBER]); | |
if (g_lpFiber[PRIMARY_FIBER] == NULL) { | |
printf("ConvertThreadToFiber error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
// | |
// Initialize the primary fiber data structure. We don't use | |
// the primary fiber data structure for anything in this sample. | |
// | |
fs[PRIMARY_FIBER].dwParameter = 0; | |
fs[PRIMARY_FIBER].dwFiberResultCode = 0; | |
fs[PRIMARY_FIBER].hFile = INVALID_HANDLE_VALUE; | |
g_lpFiber[READ_FIBER]=CreateFiber(0, ReadFiberFunc, &fs[READ_FIBER]); | |
if (g_lpFiber[READ_FIBER] == NULL) { | |
printf("CreateFiber error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
fs[READ_FIBER].dwParameter = 0x12345678; | |
g_lpFiber[WRITE_FIBER]=CreateFiber(0,WriteFiberFunc,&fs[WRITE_FIBER]); | |
if (g_lpFiber[WRITE_FIBER] == NULL) { | |
printf("CreateFiber error (%d)\n", GetLastError()); | |
return RTN_ERROR; | |
} | |
fs[WRITE_FIBER].dwParameter = 0x54545454; | |
SwitchToFiber(g_lpFiber[READ_FIBER]); | |
// | |
// We have been scheduled again. Display results from the read/write fibers | |
// | |
printf("ReadFiber: result code is %lu, %lu bytes processed\n", | |
fs[READ_FIBER].dwFiberResultCode, fs[READ_FIBER].dwBytesProcessed); | |
printf("WriteFiber: result code is %lu, %lu bytes processed\n", | |
fs[WRITE_FIBER].dwFiberResultCode, fs[WRITE_FIBER].dwBytesProcessed); | |
DeleteFiber(g_lpFiber[READ_FIBER]); | |
DeleteFiber(g_lpFiber[WRITE_FIBER]); | |
CloseHandle(fs[READ_FIBER].hFile); | |
CloseHandle(fs[WRITE_FIBER].hFile); | |
HeapFree(GetProcessHeap(), 0, g_lpBuffer); | |
HeapFree(GetProcessHeap(), 0, fs); | |
return RTN_OK; | |
} | |
VOID __stdcall ReadFiberFunc(LPVOID lpParameter) { | |
LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)lpParameter; | |
if (fds == NULL) { | |
printf("Passed NULL fiber data; exiting current thread.\n"); | |
return; | |
} | |
DisplayFiberInfo(); | |
fds->dwBytesProcessed = 0; | |
while (1) { | |
if (!ReadFile(fds->hFile, g_lpBuffer, BUFFER_SIZE, &g_dwBytesRead, NULL)) { | |
break; | |
} | |
if (g_dwBytesRead == 0) { break; } | |
fds->dwBytesProcessed += g_dwBytesRead; | |
SwitchToFiber(g_lpFiber[WRITE_FIBER]); | |
} | |
fds->dwFiberResultCode = GetLastError(); | |
SwitchToFiber(g_lpFiber[PRIMARY_FIBER]); | |
} | |
VOID __stdcall WriteFiberFunc(LPVOID lpParameter) { | |
LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)lpParameter; | |
DWORD dwBytesWritten; | |
if (fds == NULL) { | |
printf("Passed NULL fiber data; exiting current thread.\n"); | |
return; | |
} | |
DisplayFiberInfo(); | |
fds->dwBytesProcessed = 0; | |
fds->dwFiberResultCode = ERROR_SUCCESS; | |
while (1) { | |
if (!WriteFile(fds->hFile, g_lpBuffer, g_dwBytesRead, &dwBytesWritten, NULL)) { | |
break; | |
} | |
fds->dwBytesProcessed += dwBytesWritten; | |
SwitchToFiber(g_lpFiber[READ_FIBER]); | |
} | |
fds->dwFiberResultCode = GetLastError(); | |
SwitchToFiber(g_lpFiber[PRIMARY_FIBER]); | |
} | |
void DisplayFiberInfo(void) { | |
LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)GetFiberData(); | |
LPVOID lpCurrentFiber = GetCurrentFiber(); | |
if (lpCurrentFiber == g_lpFiber[READ_FIBER]) { | |
printf("Read fiber entered"); | |
} else { | |
if (lpCurrentFiber == g_lpFiber[WRITE_FIBER]) { | |
printf("Write fiber entered"); | |
} else { | |
if (lpCurrentFiber == g_lpFiber[PRIMARY_FIBER]) { | |
printf("Primary fiber entered"); | |
} else { | |
printf("Unknown fiber entered"); | |
} | |
} | |
} | |
printf(" (dwParameter is 0x%lx)\n", fds->dwParameter); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment