Code:
#IF 0 **************************************************************************************** * ' CCAPIPE.BAS Basic Anonymous Pipe as A job queue Demo ' Anonymous pipe is read by a Separate 'worker' thread ' Using anonymous pipe because win/9x cannot create named pipes ' Author: Michael Mattias Racine WI 10/29/03 ' Compiler: PB/CC 3.02 ' Win32API.INC: May 9 2002 ' Public Domain **************************************************************************************** #ENDIF #COMPILE EXE #REGISTER NONE #DEBUG ERROR ON #TOOLS ON '<<< need for TRACE, CALLSTK etc #DIM ALL #INCLUDE "Win32API.INC" ' ===[if no WIn32API.INC included, need these for Win/98 speedup]======= #IF NOT %DEF(%SW_HIDE) %SW_HIDE = 0& #ENDIF #IF NOT %DEF(%SW_SHOW) %SW_SHOW = 5& #ENDIF #IF NOT %DEF(%WINAPI) DECLARE FUNCTION ShowWindow LIB "USER32.DLL" ALIAS "ShowWindow" (BYVAL hWnd AS DWORD, BYVAL nCmdShow AS LONG) AS LONG #ENDIF ' ===[end Win/98 speedup #INCLUDEs]======= FUNCTION WINMAIN( BYVAL hInstance AS LONG , _ BYVAL hPrevInst AS LONG , _ BYVAL lpszCmdLine AS ASCIIZ PTR, _ BYVAL nCmdShow AS LONG ) AS LONG ' speed up console operations ShowWindow CONSHNDL, %SW_HIDE CONSOLE SCREEN 26,80 ShowWindow CONSHNDL, %SW_SHOW CALL MainDriver MainExit: PRINT "end of Anonymous Pipe Demo, any key to exit" WAITKEY$ END FUNCTION %PIPE_ACTION_DATA = 1 %PIPE_ACTION_EOF = 16 %PIPE_BUFFER_SIZE = 1024 * 1024 ' 1 Mb TYPE ThreadDataType Action AS DWORD AppData AS STRING * 16 END TYPE TYPE ThreadParmsType hPipeRead AS LONG hEventReady AS LONG END TYPE ' main function ' 1. Create an anonymous pipe ' 2. Start a thread whose job it is to read from that pipe ' 3. Write a bunch of data to the pipe ' 4. Write an end of thread data record to signal pipe server that there is ' no more to do ' 5. wait on server to process all loads ' 6. Exit ' relevant declares from win32API.INC 'DECLARE FUNCTION ReadFile LIB "KERNEL32.DLL" ALIAS "ReadFile" _ ' (BYVAL hFile AS DWORD, lpBuffer AS ANY, _ ' BYVAL nNumberOfBytesToRead AS LONG, lpNumberOfBytesRead AS LONG, lpOverlapped AS OVERLAPPED) AS LONG 'DECLARE FUNCTION WriteFile LIB "KERNEL32.DLL" ALIAS "WriteFile" _ ' (BYVAL hFile AS DWORD, lpBuffer AS ANY,_ ' BYVAL nNumberOfBytesToWrite AS LONG, lpNumberOfBytesWritten AS LONG, lpOverlapped AS OVERLAPPED) AS LONG ' ALSO hRead and hWrite are procedure names in Win32API.INC sos may not be used as vars. FUNCTION MainDriver () AS LONG LOCAL TP AS ThreadParmsType, hpRead AS LONG, hpWrite AS LONG LOCAL TD AS ThreadDataType LOCAL lRet AS LONG, dwParm AS DWORD, hThread AS LONG, Z AS LONG LOCAL nLoads AS LONG LOCAL cchToWrite AS LONG, cchWritten AS LONG, lpWrite AS DWORD nLOADS = 20 ' number of records we will feed to the pipe server ' create an anonymous pipe: lRet = CreatePipe (hpRead, hpWrite, BYVAL %NULL, BYVAL %PIPE_BUFFER_SIZE) IF ISTRUE lret THEN TP.hPipeRead = hpRead dwParm = VARPTR (TP) TP.hEventReady = CreateEvent (BYVAL %NULL, %TRUE, %FALSE, BYVAL %NULL) THREAD CREATE PipeThreadFunction (dwParm) TO hThread ' wait for thread function to copy parameter data to LOCAL var: WaitForSingleObject TP.hEventReady, %INFINITE CloseHandle TP.hEventReady ' Write a bunch of 'to do' records to the pipe: FOR Z = 1 TO nLoads TD.Action = %PIPE_ACTION_DATA TD.AppData = "Load #" & STR$(Z) lpWrite = VARPTR(TD) cchToWrite = SIZEOF(TD) lret = WriteFile (hpWrite, BYVAL lpWrite, cchtoWrite, cchWritten, BYVAL %NULL) IF ISFALSE lRet THEN STDOUT "Write to PIPE (DATA) FAILED" EXIT FOR END IF NEXT ' write an 'end of data' record TD.Action = %PIPE_ACTION_EOF TD.Appdata = "No More" lpWrite = VARPTR(TD) cchtoWrite = SIZEOF(TD) lret = WriteFile (hpWrite, BYVAL lpWrite, cchtoWrite, cchWritten, BYVAL %NULL) IF ISFALSE lRet THEN STDOUT "Write to PIPE (EOF) FAILED" END IF ' wait for thread to complete processing of all data in the pipe STDOUT "Primary thread completed writing; now waiting on pipe server to complete tasks." lRet = WaitForSingleObject (hThread, %INFINITE) CloseHandle hpWrite ' 'who closes the read handle? I do CloseHandle hpRead ELSE STDOUT "CreatePipe failed" END IF END FUNCTION ' ========================================================= ' WORKER THREAD WHICH READS FROM PIPE AND PROCESSES DATA ' ========================================================= FUNCTION PipeThreadFunction (BYVAL dwPARm AS LONG) AS LONG LOCAL pTP AS ThreadParmsType PTR, TP AS ThreadParmsType LOCAL TD AS ThreadDataType LOCAL cchToRead AS LONG, cchRead AS LONG, lpReadBuff AS DWORD LOCAL lRet AS LONG pTP = dwParm TP = @pTP ' tell main thread we have copied our parameter data to a local var and ' he's free to use it if he needs it: SetEvent TP.HEventReady ' read from pipe parameters lpReadBuff = VARPTR(TD) cchToRead = SIZEOF(TD) DO lRet = ReadFile (TP.hPipeRead, BYVAL lpReadBuff, cchToread, cchRead, BYVAL %NULL) IF ISTRUE lret THEN IF TD.Action = %PIPE_ACTION_DATA THEN STDOUT "Processing data from pipe==>" & TD.Appdata SLEEP 3000 ELSEIF TD.Action = %PIPE_ACTION_EOF THEN STDOUT "Got EOF record:" & TD.AppData & ", exiting" EXIT DO END IF ELSE STDOUT "Read File (from Pipe) Failed" EXIT DO END IF LOOP END FUNCTION ' *** END OF FILE ***
------------------
Michael Mattias
Tal Systems Inc.
Racine WI USA
mailto:[email protected][email protected]</A>
www.talsystems.com
Comment