FIBERS.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:
Windows编程
开发平台:
Visual C++
- /*++
- Copyright (c) 1995-1997 Microsoft Corporation
- Module Name:
- fibers.c
- Abstract:
- This module illustrates the Win32 fiber APIs.
- This example implements a fiber based file copy operation. Note that
- a number of different techiques exists for copying files programmatically;
- this sample simply illustrates the fiber APIs.
- This example makes use of a fiber data structure which is used to
- determine the behavior and state of the fiber. One data structure
- exists for each fiber; the pointer to the data structure is passed
- to the fiber at fiber creation time via the lpParameter fiber parameter.
- The executing thread in the process makes a call to ConvertThreadToFiber,
- which allows fibers to be scheduled by the caller. This also allows
- the resultant fiber to be scheduled by another fiber.
- Next, two additional fibers are created, one fiber which performs read
- operations against a specified file, and another fiber which performs
- the write operations against a specified file.
- The primary fiber then schedules the read fiber. After a succesful
- read, the read fiber schedules the write fiber. After a succesful write
- in the write fiber, the write fiber schedules the read fiber. When
- the read/write cycle has completed, the primary fiber is scheduled,
- which results in the display of the read/write status. If an error occurs
- during the read or write fibers, the primary fiber is scheduled and status
- of the read/write is displayed.
- The fibers, fiber data structures, and file handles are then freed
- prior to process termination.
- Author:
- Scott Field (sfield) 30-Nov-95
- Revision History:
- --*/
- #include <windows.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 // total number of 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
- main(
- int argc,
- char *argv[]
- )
- {
- LPFIBERDATASTRUCT fs;
- if(argc != 3) {
- printf("Usage: %s <SourceFile> <DestinationFile>n", argv[0]);
- return RTN_USAGE;
- }
- //
- // allocate storage for our fiber data structures
- //
- fs = (LPFIBERDATASTRUCT)HeapAlloc(
- GetProcessHeap(), 0, sizeof(FIBERDATASTRUCT) * FIBER_COUNT);
- if(fs == NULL) {
- printf("HeapAlloc error! (rc%=lu)n", GetLastError());
- return RTN_ERROR;
- }
- //
- // allocate storage for the read/write buffer
- //
- g_lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BUFFER_SIZE);
- if(g_lpBuffer == NULL) {
- printf("HeapAlloc error! (rc=%lu)n", GetLastError());
- return RTN_ERROR;
- }
- //
- // open the source file
- //
- 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! (rc=%lu)n", GetLastError());
- return RTN_ERROR;
- }
- //
- // open the destination file
- //
- 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! (rc=%lu)n", GetLastError());
- return RTN_ERROR;
- }
- //
- // convert this thread to a fiber, to allow scheduling of other fibers
- //
- g_lpFiber[PRIMARY_FIBER] = ConvertThreadToFiber(&fs[PRIMARY_FIBER]);
- if(g_lpFiber[PRIMARY_FIBER] == NULL) {
- printf("ConvertThreadToFiber failed! rc=%lun", GetLastError());
- return RTN_ERROR;
- }
- //
- // Just 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;
- //
- // create the Read fiber
- //
- g_lpFiber[READ_FIBER] = CreateFiber(0, ReadFiberFunc, &fs[READ_FIBER]);
- if(g_lpFiber[READ_FIBER] == NULL) {
- printf("CreateFiber error! (rc=%lu)n", GetLastError());
- return RTN_ERROR;
- }
- fs[READ_FIBER].dwParameter = 0x12345678;
- //
- // create the Write fiber
- //
- g_lpFiber[WRITE_FIBER]=CreateFiber(0, WriteFiberFunc, &fs[WRITE_FIBER]);
- if(g_lpFiber[WRITE_FIBER] == NULL) {
- printf("CreateFiber error! (rc=%lu)n", GetLastError());
- return RTN_ERROR;
- }
- fs[WRITE_FIBER].dwParameter = 0x54545454;
- //
- // switch to the read fiber
- //
- SwitchToFiber(g_lpFiber[READ_FIBER]);
- //
- // We have now been scheduled again. Display results from the read/write
- // fibers
- //
- printf("ReadFiber result == %lu Bytes Processed == %lun",
- fs[READ_FIBER].dwFiberResultCode, fs[READ_FIBER].dwBytesProcessed);
- printf("WriteFiber result == %lu Bytes Processed == %lun",
- fs[WRITE_FIBER].dwFiberResultCode, fs[WRITE_FIBER].dwBytesProcessed);
- //
- // Delete the fibers
- //
- DeleteFiber(g_lpFiber[READ_FIBER]);
- DeleteFiber(g_lpFiber[WRITE_FIBER]);
- //
- // close handles
- //
- CloseHandle(fs[READ_FIBER].hFile);
- CloseHandle(fs[WRITE_FIBER].hFile);
- //
- // free allocated memory
- //
- HeapFree(GetProcessHeap(), 0, g_lpBuffer);
- HeapFree(GetProcessHeap(), 0, fs);
- return RTN_OK;
- }
- VOID
- __stdcall
- ReadFiberFunc(
- LPVOID lpParameter
- )
- {
- LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)lpParameter;
- //
- // if this fiber was passed NULL for fiber data, just return,
- // causing the current thread to exit
- //
- if(fds == NULL) {
- printf("Passed NULL fiber data. Exiting current thread.n");
- return;
- }
- //
- // display some information pertaining to the current fiber
- //
- DisplayFiberInfo();
- fds->dwBytesProcessed = 0;
- while(1) {
- //
- // read data from file specified in the READ_FIBER data structure
- //
- if(!ReadFile(fds->hFile, g_lpBuffer, BUFFER_SIZE, &g_dwBytesRead, NULL)) {
- break;
- }
- //
- // if we reached EOF, break
- //
- if(g_dwBytesRead == 0) break;
- //
- // update number of bytes processed in the fiber data structure
- //
- fds->dwBytesProcessed += g_dwBytesRead;
- //
- // switch to the write fiber
- //
- SwitchToFiber(g_lpFiber[WRITE_FIBER]);
- } // while
- //
- // update the fiber result code
- //
- fds->dwFiberResultCode = GetLastError();
- //
- // switch back to the primary fiber
- //
- SwitchToFiber(g_lpFiber[PRIMARY_FIBER]);
- }
- VOID
- __stdcall
- WriteFiberFunc(
- LPVOID lpParameter
- )
- {
- LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)lpParameter;
- DWORD dwBytesWritten;
- //
- // if this fiber was passed NULL for fiber data, just return,
- // causing the current thread to exit
- //
- if(fds == NULL) {
- printf("Passed NULL fiber data. Exiting current thread.n");
- return;
- }
- //
- // display some information pertaining to the current fiber
- //
- DisplayFiberInfo();
- //
- // assume all of the writes succeed. If a write fails, the fiber
- // result code will be updated to reflect the reason for failure
- //
- fds->dwBytesProcessed = 0;
- fds->dwFiberResultCode = ERROR_SUCCESS;
- while (1) {
- //
- // write data to the file specified in the WRITE_FIBER data structure
- //
- if(!WriteFile(fds->hFile, g_lpBuffer, g_dwBytesRead, &dwBytesWritten, NULL)) {
- //
- // if an error occurred writing, break
- //
- break;
- }
- //
- // update number of bytes processed in the fiber data structure
- //
- fds->dwBytesProcessed += dwBytesWritten;
- //
- // switch back to the read fiber
- //
- SwitchToFiber(g_lpFiber[READ_FIBER]);
- } // while
- //
- // if an error occurred, update the fiber result code...
- //
- fds->dwFiberResultCode = GetLastError();
- //
- // ...and switch to the primary fiber
- //
- SwitchToFiber(g_lpFiber[PRIMARY_FIBER]);
- }
- void
- DisplayFiberInfo(
- void
- )
- {
- LPFIBERDATASTRUCT fds = (LPFIBERDATASTRUCT)GetFiberData();
- LPVOID lpCurrentFiber = GetCurrentFiber();
- //
- // determine which fiber we are executing, based on the fiber address
- //
- 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");
- }
- }
- //
- // display dwParameter from the current fiber data structure
- //
- printf(" (dwParameter == 0x%lx)n", fds->dwParameter);
- }