From: SMTP%"DSJ@WKUVX1.WKU.EDU" 9-APR-1994 15:21:52.25 To: EVERHART CC: Subj: FEBRUARY94.THREAD X-FileServer: Digital Systems Journal File Server Date: Sat, 09 Apr 1994 14:22:26 CDT Sender: DSJ-Mgr@WKUVX1.WKU.EDU Errors-To: DSJ-Mgr@WKUVX1.WKU.EDU Warnings-To: <> From: DSJ-Mgr@WKUVX1.WKU.EDU Reply-To: DSJ@WKUVX1.WKU.EDU Subject: FEBRUARY94.THREAD To: EVERHART@arisia.gce.com $! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_UNPACK_VERIFY"))' $! $! This archive created: $! Name : THREAD $! By : Hunter Goatley $! Date : 7-FEB-1994 07:39:02.63 $! Using: VMS_SHARE 8.4, (C) 1993 Andy Harper, Kings College London UK $! $! Credit is due to these people for their original ideas: $! James Gray, Michael Bednarek $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. THREAD.DSJ;1 $! $ set="set" $ set symbol/scope=(nolocal,noglobal) $ f=f$parse("SHARE_UNPACK_TEMP","SYS$SCRATCH:."+f$getjpi("","PID")) $ e="write sys$error ""%UNPACK"", " $ w="write sys$output ""%UNPACK"", " $ if .not. f$trnlnm("SHARE_UNPACK_LOG") then $ w = "!" $ if f$getsyi("CPU") .gt. 127 then $ goto start $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto start $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $unpack: subroutine ! P1=filename, P2=checksum, P3=attributes,P4=size $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'" $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn' File skipped" $ delete 'f'* $ exit $dirok: $ x=f$search(P1) $ if x .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped" $ delete 'f'* $ exit $file_absent: $ w "-I-UNPACK, Unpacking ", P5, " of ", P6, " - ", P1, " - ", P4, " Blocks" $ n=P1 $ if P3 .nes. "" then $ n=f $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT/NOJOURNAL 'f'/OUT='n' PROCEDURE GetHex(s,p)LOCAL x1,x2;x1:=INDEX(t,SUBSTR(s,p,1))-1;x2:=INDEX(t, SUBSTR(s,p+1,1))-1;RETURN 16*x1+x2;ENDPROCEDURE;PROCEDURE SkipPartsep LOCAL m; LOOP m:=MARK(NONE);EXITIF m=END_OF(b);DELETE(m);EXITIF INDEX(ERASE_LINE, "-+-+-+-+-+-+-+-+")=1;ENDLOOP;ENDPROCEDURE;PROCEDURE ProcessLine LOCAL c,s,l,b, n,p;c := ERASE_CHARACTER(1);s := ERASE_LINE;IF c = "X" THEN SPLIT_LINE; ENDIF; MOVE_HORIZONTAL(-1);l := LENGTH(s);p := 1;LOOP EXITIF p > l;c := SUBSTR(s,p,1); p := p+1;CASE c FROM ' ' TO '`' ['`']: COPY_TEXT(ASCII(GetHex(s,p))); p:=p+2;[ ' ']: p:=p+1;[INRANGE,OUTRANGE]: COPY_TEXT(c);ENDCASE;ENDLOOP;ENDPROCEDURE; PROCEDURE Decode LOCAL m;POSITION(BEGINNING_OF(b));LOOP m:=MARK(NONE);EXITIF m= END_OF(b);DELETE(m);IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+-")= 1 THEN SkipPartSep;ELSE ProcessLine;MOVE_HORIZONTAL(1);ENDIF;ENDLOOP; ENDPROCEDURE;SET(FACILITY_NAME,"UNPACK");SET(SUCCESS,OFF);SET(INFORMATIONAL, OFF);t:="0123456789ABCDEF";f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);Decode;WRITE_FILE(b,GET_INFO(COMMAND_LINE,"output_file")); QUIT; $ if p3 .eqs. "" then $ goto dl $ open/write fdl &f $ write fdl "RECORD" $ write fdl P3 $ close fdl $ w "-I-CONVRFM, Converting record format to ", P3 $ convert/fdl=&f &f-1 &P1 $dl: delete 'f'* $ checksum 'P1' $ if checksum$checksum .nes. P2 then $ - e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ exit $ endsubroutine $start: $! $ create 'f' XMTHREAD1.C`20(main`20program) X X/* X`20*`20mthread1.c`20-`20demonstrate`20creation`20and`20use`20of`20a`20second V`20thread X`20*/ X X#include`20 X#include`20 X#include`20 X#include`20 X#include`20 X X#include`20"absque.h" X#include`20"comport1.h" X X/*`20structures`20*/ X Xstruct`20work_item_s`20`7B X`09struct`20qhdr_s`20qhdr; X`09char`20c; X`7D; X X/*`20global`20storage`20*/ X XHANDLE`09`20Port_handle,`20Write_thread,`20Trigger_writes_event; XCRITICAL_SECTION`09Cs_qhdr; XDWORD`20Write_thread_id; X Xstruct`20qhdr_s`20Work_queue_head; X X/*`20function`20forward`20references`20*/ X Xstart_write_thread(); Xvoid`20write_loop(); Xvoid`20read_loop(); X Xint`20main() X`7B X`09DWORD`09`20the_error; X X`09the_error`20=`20open_the_port("COM2",`20`26Port_handle); X`09if`20(the_error) X`09`09return`20the_error; X X`09InitializeCriticalSection(`26Cs_qhdr); X`09init_queue(`26Work_queue_head,`20`26Cs_qhdr); X X`09Trigger_writes_event`20=`20CreateEvent( X`09`09`09`09`090,`09`09`09`09/*`20 Xno`20security`20attributes`20*/ X`09`09`09`09`09FALSE,`09`09`09/*`20not`20 Xmanual`20reset`20*/ X`09`09`09`09`09FALSE,`09`09`09/*`20initial`20 Xstate`20=`20nonsignalled`20*/ X`09`09`09`09`09NULL);`09`09`09/*`20no`20name`20 X*/ X X`09if`20(Trigger_writes_event`20==`20(HANDLE)NULL) X`09`09return`20GetLastError(); X X`09the_error`20=`20start_write_thread(); X`09if`20(the_error) X`09`09return`20the_error; X X`09read_loop();`09/*`20returns`20upon`20reading`20Ctl-Z`20*/ X X`09the_error`20=`20close_the_port(`26Port_handle); X`09if`20(the_error) X`09`09return`20the_error; X X`09return`20EXIT_SUCCESS; X`7D X Xstart_write_thread() X`7B X`09Write_thread`20=`20CreateThread( X`09`09NULL,`20`09`09`09`09/*`20no`20security`20attributes`20 X*/ X`09`090,`09`09`09`09`09/*`20use`20default`20 Xstack`20size`20*/ X`09`09(LPTHREAD_START_ROUTINE)`20write_loop,`09/*`20thread`20function`20 X*/ X`09`090,`09`09`09`09`09/*`20no`20arg`20to`20thread`20 Xfunction`20*/ X`09`090,`09`09`09`09`09/*`20default`20creation`20 Xflags`20*/ X`09`09`26`20Write_thread_id); X X`09if`20(Write_thread`20==`20NULL)`20`7B X`09`09printf("Error`20from`20CreateThread()`5Cn"); X`09`09return`20GetLastError(); X`09`7D X`09return`20NO_ERROR; X`7D X Xvoid Xwrite_loop() X`7B X`09struct`20work_item_s`20*workitem; X X`09while`20(TRUE)`20`7B X`09`09WaitForSingleObject(Trigger_writes_event,`20INFINITE); X X`09`09while`20(QUEUE_WAS_EMPTY`20!=`20 X`09`09`20remque(Work_queue_head.flink,`20(struct`20qhdr_s`20**)`26workitem,`20 V X`26Cs_qhdr))`20`7B X`09`09`09_putch(workitem->c); X`09`09`09free((void`20*)workitem); X`09`09`7D X`09`7D`09 X X`7D X Xvoid Xread_loop() X`7B X#define`20CTRLZ`2026 X X`09char`20c; X`09DWORD`20insize; X`09BOOL`20status; X`09struct`20work_item_s`20*workitem; X X`09while`20(TRUE)`20`7B X`09`09status`20=`20ReadFile(Port_handle,`20`26c,`20sizeof(c),`20`26insize,`20 V XNULL); X X`09`09if`20(!status`20`7C`7C`20c`20==`20CTRLZ) X`09`09`09break; X X`09`09workitem`20=`20malloc(sizeof(struct`20work_item_s)); X`09`09workitem->c`20=`20c; X`09`09insque((struct`20qhdr_s`20*)workitem,`20Work_queue_head.blink,`20 X`26Cs_qhdr); X`09`09SetEvent(Trigger_writes_event); X`09`7D X`7D X X`0C X Xabsque.h`20(use`20with`20both`20mthread1.c`20and`20mthread2.c) X Xstruct`20qhdr_s`20`7B X`09struct`20qhdr_s`20*flink,`20*blink; X`7D; X X#define`20QUEUE_WAS_EMPTY`20-1 X#define`20QUEUE_NOW_EMPTY`200 X#define`20QUEUE_NOT_EMPTY`201 X Xvoid`20init_queue(struct`20qhdr_s`20*qhdr,`20CRITICAL_SECTION`20*cs); Xremque(struct`20qhdr_s`20*entry,`20struct`20qhdr_s`20**addr,`20CRITICAL_SECTIO VN`20*cs); Xinsque(struct`20qhdr_s`20*entry,`20struct`20qhdr_s`20*pred,`20CRITICAL_SECTION V`20*cs); X X`0C X Xabsque.c`20(use`20with`20both`20mthread1.c`20and`20mthread2.c) X X#include`20 X#include`20"absque.h" X Xvoid Xinit_queue(struct`20qhdr_s`20*qhdr,`20CRITICAL_SECTION`20*cs) X`7B X`09EnterCriticalSection(cs); X`09qhdr->flink`20=`20qhdr; X`09qhdr->blink`20=`20qhdr; X`09LeaveCriticalSection(cs); X`7D X Xremque(struct`20qhdr_s`20*entry,`20struct`20qhdr_s`20**addr,`20CRITICAL_SECTIO VN`20*cs) X`7B X`09struct`20qhdr_s`20*pred,`20*next; X X`09EnterCriticalSection(cs); X X`09if`20(entry`20==`20entry->blink)`20`7B X`09`09*addr`20=`20(struct`20qhdr_s`20*)NULL; X`09`09LeaveCriticalSection(cs); X`09`09return`20QUEUE_WAS_EMPTY; X`09`7D X X`09pred`20=`20entry->blink; X`09next`20=`20entry->flink; X`09pred->flink`20=`20entry->flink; X`09next->blink`20=`20entry->blink; X`09*addr`20=`20entry; X X`09if`20(pred`20==`20next)`20`7B X`09`09LeaveCriticalSection(cs); X`09`09return`20QUEUE_NOW_EMPTY; X`09`7D X X`09LeaveCriticalSection(cs); X`09return`20QUEUE_NOT_EMPTY; X`7D X Xinsque(struct`20qhdr_s`20*entry,`20struct`20qhdr_s`20*pred,`20CRITICAL_SECTION V`20*cs) X`7B X`09EnterCriticalSection(cs); X X`09entry->flink`20=`20pred->flink; X`09entry->blink`20=`20pred; X`09(pred->flink)->blink`20=`20entry; X`09pred->flink`20=`20entry; X X`09if`20(entry->flink`20==`20entry->blink)`20`7B X`09`09LeaveCriticalSection(cs); X`09`09return`20QUEUE_WAS_EMPTY; X`09`7D X X`09LeaveCriticalSection(cs); X`09return`20QUEUE_NOT_EMPTY; X`7D X X`0C X Xcomport1.h X Xopen_the_port(char`20*portname,`20HANDLE`20*port_handle); Xclose_the_port(HANDLE`20*port_handle); X X`0C X Xcomport1.c X X#include`20 X#include`20 X#include`20 X#include`20"comport1.h" X XDCB`09Dcb_old; X Xopen_the_port(char`20*portname,`20HANDLE`20*port_handle) X`7B X`09BOOL`09status; X`09DCB`09`09dcb_new; X X`09*port_handle`20=`20CreateFile( X`09`09portname, X`09`09GENERIC_READ`20`7C`20GENERIC_WRITE,`09`09/*`20required`20for`20 Xcomm`20dvcs`20*/ X`09`090,`09`09`09`09`09`09`09`09 X`09/*`20exclusive`20access`20-`20req'd`20*/ X`09`09NULL,`09`09`09`09`09`09`09`09 X/*`20no`20security`20attributes`20*/ X`09`09OPEN_EXISTING,`09`09`09`09`09`09/*`20 Xrequired`20for`20comm`20dvcs`20*/ X`09`090,`09`09`09`09`09`09`09`09 X`09/*`20not`20overlapped`20I/O`20*/ X`09`09NULL);`09`09`09`09`09`09`09`09 X/*`20required`20for`20comm`20dvcs`20*/ X X`09if`20(*port_handle`20==`20INVALID_HANDLE_VALUE) X`09`09return`20GetLastError(); X X`09/*`20get`20the`20current`20state`20of`20the`20port`20so`20we`20can`20modify V`20it`20and X`09`20*`20restore`20it`20*/ X X`09status`20=`20GetCommState(*port_handle,`20`26Dcb_old); X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20GetCommState()`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09/*`20specify`20our`20changes`20*/ X X`09dcb_new`20=`20Dcb_old; X`09dcb_new.BaudRate`20=`209600; X`09dcb_new.ByteSize`20=`208; X`09dcb_new.Parity`20=`20NOPARITY; X`09dcb_new.StopBits`20=`20ONESTOPBIT; X X`09status`20=`20SetCommState(*port_handle,`20`26dcb_new); X X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20SetCommState()`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09return`20NO_ERROR; X`7D X Xclose_the_port(HANDLE`20*port_handle) X`7B X`09BOOL`09status; X X`09/*`20restore`20the`20port`20*/ X X`09status`20=`20SetCommState(*port_handle,`20`26Dcb_old); X X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20SetCommState()`5Cn"); X`20`09`09return`20EXIT_FAILURE; X`09`7D X X`09status`20=`20CloseHandle(*port_handle); X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20CloseHandle()`20on`20comm`20port`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09return`20NO_ERROR; X`7D X X`0C X Xmthread1.mak,`20the`20make`20file`20for`20mthread1 X X#`20Microsoft`20Visual`20C++`20generated`20build`20script`20-`20Do`20not`20mod Vify X XPROJ`20=`20MTHREAD1 XDEBUG`20=`201 XPROGTYPE`20=`202 XCALLER`20=`20 XARGS`20=`20 XDLLS`20=`20 XORIGIN`20=`20MSVCNT XORIGIN_VER`20=`201.00 XPROJPATH`20=`20C:`5CTFR`5CARTICLES31-JAN-94`2009:06:28SJ`5CMTHREAD1`5C`20 XUSEMFC`20=`200 XCC`20=`20cl XCPP`20=`20cl XCXX`20=`20cl XCCREATEPCHFLAG`20=`20 XCPPCREATEPCHFLAG`20=`20 XCUSEPCHFLAG`20=`20 XCPPUSEPCHFLAG`20=`20 XFIRSTC`20=`20MTHREAD1.C XFIRSTCPP`20=`20 XRC`20=`20rc XCFLAGS_D_DEXE32`20=`20/nologo`20/W3`20/Zi`20/YX`20/D`20"_X86_"`20/D`20"_DEBUG" V`20/D`20"_CONSOLE"`20/FR X/MT`20/Fd"MTHREAD1.PDB"`20/Fp"MTHREAD1.PCH" XCFLAGS_R_DEXE32`20=`20/nologo`20/W3`20/YX`20/O2`20/D`20"_X86_"`20/D`20"NDEBUG" V`20/D`20"_CONSOLE"`20/FR X/ML`20/Fp"MTHREAD1.PCH" XLFLAGS_D_DEXE32`20=`20/NOLOGO`20/DEBUG`20/DEBUGTYPE:cv`20/SUBSYSTEM:console`20 Vnetapi32.lib XLFLAGS_R_DEXE32`20=`20/NOLOGO`20/SUBSYSTEM:console`20netapi32.lib XLFLAGS_D_LIB32`20=`20/NOLOGO XLFLAGS_R_LIB32`20=`20/NOLOGO XLIBS_D_DEXE32`20=`20 XLIBS_R_DEXE32`20=`20 XRCFLAGS32`20=`20 XD_RCDEFINES32`20=`20-d_DEBUG XR_RCDEFINES32`20=`20-dNDEBUG XOBJS_EXT`20=`20 XLIBS_EXT`20=`20 X!if`20"$(DEBUG)"`20==`20"1" XCFLAGS`20=`20$(CFLAGS_D_DEXE32) XLFLAGS`20=`20$(LFLAGS_D_DEXE32) XLIBS`20=`20$(LIBS_D_DEXE32) XLFLAGS_LIB=$(LFLAGS_D_LIB32) XMAPFILE_OPTION`20=`20 XRCDEFINES`20=`20$(D_RCDEFINES32) X!else XCFLAGS`20=`20$(CFLAGS_R_DEXE32) XLFLAGS`20=`20$(LFLAGS_R_DEXE32) XLIBS`20=`20$(LIBS_R_DEXE32) XMAPFILE_OPTION`20=`20 XLFLAGS_LIB=$(LFLAGS_R_LIB32) XRCDEFINES`20=`20$(R_RCDEFINES32) X!endif XSBRS`20=`20MTHREAD1.SBR`20`5C X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20ABSQUE.SBR`20`5C X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20COMPORT.SBR X X XMTHREAD1_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cabsque.h`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Ccomport.h X X XABSQUE_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cabsque.h X X XCOMPORT_DEP`20=`20 X Xall:`20`20`20`20$(PROJ).EXE`20$(PROJ).BSC X XMTHREAD1.OBJ:`20`20`20MTHREAD1.C`20$(MTHREAD1_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CCREATEPCHFLAG)`20/c`20MTHREAD1. VC X XABSQUE.OBJ:`20`20`20`20`20ABSQUE.C`20$(ABSQUE_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CUSEPCHFLAG)`20/c`20ABSQUE.C X XCOMPORT.OBJ:`20`20`20`20COMPORT.C`20$(COMPORT_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CUSEPCHFLAG)`20/c`20COMPORT.C X X$(PROJ).EXE:`20`20`20`20MTHREAD1.OBJ`20ABSQUE.OBJ`20COMPORT.OBJ`20$(OBJS_EXT) V`20$(LIBS_EXT) X`20`20`20`20`20`20`20`20echo`20>NUL`20@<<$(PROJ).CRF XMTHREAD1.OBJ`20 XABSQUE.OBJ`20 XCOMPORT.OBJ`20 X$(OBJS_EXT) X-OUT:$(PROJ).EXE X$(MAPFILE_OPTION) X$(LIBS) X$(LIBS_EXT) X$(DEFFILE_OPTION)`20-implib:$(PROJ).lib X<< X`20`20`20`20`20`20`20`20link`20$(LFLAGS)`20@$(PROJ).CRF X Xrun:`20$(PROJ).EXE X`20`20`20`20`20`20`20`20$(PROJ)`20$(RUNFLAGS) X X X$(PROJ).BSC:`20$(SBRS) X`20`20`20`20`20`20`20`20bscmake`20@<< X/o$@`20$(SBRS) X X X X<< X X`0C X Xmthread2.c X X/* X`20*`20mthread2.c`20-`20demonstrate`20use`20of`20multiple`20threads X`20*/ X X#include`20 X#include`20 X#include`20 X#include`20 X#include`20 X X#include`20"absque.h" X#include`20"comport2.h" X#include`20"console2.h" X X/*`20structures`20*/ X Xstruct`20work_item_s`20`7B X`09struct`20qhdr_s`20qhdr; X`09char`20c; X`7D; X X/*`20global`20storage`20*/ X XHANDLE`09Port_handle, X`09`09Write_console_handle, X`09`09Read_console_handle, X`09`09Write_port_event, X`09`09Write_console_event, X`09`09Done_event; X XCRITICAL_SECTION`09Write_port_cs, X`09`09`09`09`09Write_console_cs; X XOVERLAPPED`09Write_port_olap, X`09`09`09Read_port_olap; X XDWORD`09Write_port_threadid, X`09`09Read_port_threadid, X`09`09Write_console_threadid, X`09`09Read_console_threadid; X Xstruct`20qhdr_s`20Write_port_qhd,`20Write_console_qhd; X X/*`20function`20forward`20references`20*/ X XHANDLE`20create_an_event(); XHANDLE`20start_a_thread(void`20threadfunc()); Xvoid`20write_port_loop(); Xvoid`20read_port_loop(); Xvoid`20write_console_loop(); Xvoid`20read_console_loop(); X Xint`20main() X`7B XHANDLE`09write_port_thread, X`09`09read_port_thread, X`09`09write_console_thread, X`09`09read_console_thread; X X`09DWORD`09`20the_error; X X`09the_error`20=`20open_the_port("COM2",`20`26Port_handle, X`09`09`09`09`09`26Write_port_olap,`20`26Read_port_olap); X`09if`20(the_error) X`09`09return`20the_error; X X`09the_error`20=`20open_the_console( X`09`09`09`09`26Write_console_handle,`20 X`26Read_console_handle); X`09if`20(the_error) X`09`09return`20the_error; X X`09InitializeCriticalSection(`26Write_port_cs); X`09InitializeCriticalSection(`26Write_console_cs); X`09init_queue(`26Write_port_qhd,`20`26Write_port_cs); X`09init_queue(`26Write_console_qhd,`20`26Write_console_cs); X X`09Write_port_event`20=`20create_an_event(); X`09if`20(Write_port_event`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09Write_console_event`20=`20create_an_event(); X`09if`20(Write_console_event`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09Done_event`20=`20create_an_event(); X`09if`20(Done_event`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09write_port_thread`20=`20start_a_thread(write_port_loop); X`09if`20(write_port_thread`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09write_console_thread`20=`20start_a_thread(write_console_loop); X`09if`20(write_console_thread`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09read_port_thread`20=`20start_a_thread(read_port_loop); X`09if`20(read_port_thread`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09read_console_thread`09=`20start_a_thread(read_console_loop); X`09if`20(read_console_thread`20==`20(HANDLE)`20NULL) X`09`09return`20GetLastError(); X X`09WaitForSingleObject(Done_event,`20INFINITE); X X`09the_error`20=`20close_the_port(`26Port_handle); X`09if`20(the_error) X`09`09exit(the_error); X X`09return`20EXIT_SUCCESS; X`7D X XHANDLE Xcreate_an_event() X`7B X`09return`20CreateEvent( X`09`09`09`09`090,`09`09`09`09/*`20 Xno`20security`20attributes`20*/ X`09`09`09`09`09FALSE,`09`09`09/*`20not`20 Xmanual`20reset`20*/ X`09`09`09`09`09FALSE,`09`09`09/*`20initial`20 Xstate`20=`20nonsignalled`20*/ X`09`09`09`09`09NULL);`09`09`09/*`20no`20name`20 X*/ X`7D X XHANDLE Xstart_a_thread(void`20threadfunc()) X`7B X`09DWORD`09thread_id; X X`09return`20CreateThread( X`09`09NULL,`20`09`09`09`09/*`20no`20security`20attributes`20 X*/ X`09`090,`09`09`09`09`09/*`20use`20default`20 Xstack`20size`20*/ X`09`09(LPTHREAD_START_ROUTINE)`20threadfunc,`09/*`20thread`20function`20 X*/ X`09`090,`09`09`09`09`09/*`20no`20arg`20to`20thread`20 Xfunction`20*/ X`09`090,`09`09`09`09`09/*`20default`20creation`20 Xflags`20*/ X`09`09`26thread_id); X`7D X Xvoid Xwrite_port_loop() X`7B X`09struct`20work_item_s`20*workitem; X`09DWORD`20outsize,`20err; X`09char`20c; X`09BOOL`20status; X X`09while`20(TRUE)`20`7B X`09`09WaitForSingleObject(Write_port_event,`20INFINITE); X X`09`09while`20(QUEUE_WAS_EMPTY`20!=`20 X`09`09`20remque(Write_port_qhd.flink,`20(struct`20qhdr_s`20**)`26workitem,`20 V X`26Write_port_cs))`20`7B X`09`09`09c`20=`20workitem->c; X X`09`09`09status`20=`20WriteFile( X`09`09`09`09Port_handle,`20`26c,`20sizeof(c),`20`26outsize,`20 X`26Write_port_olap); X`09`09`09if`20(!status) X`09`09`09`09err`20=`20GetLastError(); X`09`09`09`09if`20(err`20!=`20ERROR_IO_PENDING) X`09`09`09`09`09exit(err); X X`09`09`09WaitForSingleObject(Write_port_olap.hEvent,`20 XINFINITE); X X`09`09`09free((void`20*)workitem); X`09`09`7D X`09`7D`09 X X`7D X Xvoid Xwrite_console_loop() X`7B X`09struct`20work_item_s`20*workitem; X`09char`20c; X`09BOOL`20status; X`09DWORD`20outsize; X X`09while`20(TRUE)`20`7B X`09`09WaitForSingleObject(Write_console_event,`20INFINITE); X X`09`09while`20(QUEUE_WAS_EMPTY`20!=`20 X`09`09`20remque(Write_console_qhd.flink,`20(struct`20qhdr_s`20 X**)`26workitem,`20`26Write_console_cs))`20`7B X`09`09`09c`20=`20workitem->c; X X`09`09`09status`20=`20WriteFile( X`09`09`09`09Write_console_handle,`20`26c,`20sizeof(c),`20 X`26outsize,`20NULL); X`09`09`09if`20(!status) X`09`09`09`09exit(GetLastError()); X X`09`09`09free((void`20*)workitem); X`09`09`7D X`09`7D`09 X`7D X Xvoid Xread_port_loop() X`7B X`09char`20c; X`09DWORD`20insize,`20err; X`09BOOL`20status; X`09struct`20work_item_s`20*workitem; X X`09while`20(TRUE)`20`7B X`09`09status`20=`20ReadFile(Port_handle,`20`26c,`20sizeof(c),`20`26insize,`20 V X`26Read_port_olap); X`09`09if`20(!status) X`09`09`09err`20=`20GetLastError(); X`09`09`09if`20(err`20!=`20ERROR_IO_PENDING) X`09`09`09`09exit(err); X`09`09WaitForSingleObject(Read_port_olap.hEvent,`20INFINITE); X X`09`09workitem`20=`20malloc(sizeof(struct`20work_item_s)); X`09`09workitem->c`20=`20c; X`09`09insque((struct`20qhdr_s`20*)workitem,`20Write_console_qhd.blink,`20 X`26Write_console_cs); X`09`09SetEvent(Write_console_event); X`09`7D X`7D X Xvoid Xread_console_loop() X`7B X#define`20CTRLZ`2026 X X`09DWORD`20insize; X`09char`20c; X`09struct`20work_item_s`20*workitem; X`09BOOL`20status; X X`09while`20(TRUE)`20`7B X`09`09status`20=`20ReadFile( X`09`09`09Read_console_handle,`20`26c,`20sizeof(c),`20`26insize,`20NULL); X`09`09if`20(!status) X`09`09`09exit(GetLastError()); X X`09`09if`20(c`20==`20CTRLZ)`20`7B X`09`09`09SetEvent(Done_event); X`09`09`09return; X`09`09`7D X X`09`09workitem`20=`20malloc(sizeof(struct`20work_item_s)); X`09`09workitem->c`20=`20c; X`09`09insque((struct`20qhdr_s`20*)workitem,`20Write_port_qhd.blink,`20 X`26Write_port_cs); X`09`09SetEvent(Write_port_event); X`09`7D X`7D X X`0C X Xcomport2.h X Xopen_the_port(char`20*portname,`20HANDLE`20*port_handle, X`09`09`09OVERLAPPED`20*write_olap,`20OVERLAPPED`20*read_olap); Xclose_the_port(HANDLE`20*port_handle); X X`0C X Xcomport2.c X X#include`20 X#include`20 X#include`20 X#include`20"comport2.h" X XDCB`09Dcb_old; X Xopen_the_port(char`20*portname,`20HANDLE`20*port_handle, X`09`09`09OVERLAPPED`20*write_olap,`20OVERLAPPED`20*read_olap) X`7B X`09BOOL`09status; X`09DCB`09`09dcb_new; X`09COMMTIMEOUTS`20`20tmo; X X`09*port_handle`20=`20CreateFile( X`09`09portname, X`09`09GENERIC_READ`20`7C`20GENERIC_WRITE,`09`09/*`20required`20for`20 Xcomm`20dvcs`20*/ X`09`090,`09`09`09`09`09`09`09`09 X`09/*`20exclusive`20access`20-`20req'd`20*/ X`09`09NULL,`09`09`09`09`09`09`09`09 X/*`20no`20security`20attributes`20*/ X`09`09OPEN_EXISTING,`09`09`09`09`09`09/*`20 Xrequired`20for`20comm`20dvcs`20*/ X`09`09FILE_FLAG_OVERLAPPED,`09`09`09`09/*`20not`20 Xoverlapped`20I/O`20*/ X`09`09NULL);`09`09`09`09`09`09`09`09 X/*`20required`20for`20comm`20dvcs`20*/ X X`09if`20(*port_handle`20==`20INVALID_HANDLE_VALUE) X`09`09return`20GetLastError(); X X`09/*`20set`20up`20overlapped`20structures`20*/ X X`09write_olap->hEvent`20=`20CreateEvent(NULL,`20TRUE,`20FALSE,`20NULL); X`09if`20(write_olap->hEvent`20==`20NULL X`09`20`7C`7C`20!ResetEvent(write_olap->hEvent)) X`09`09return`20GetLastError(); X X`09read_olap->hEvent`20=`20CreateEvent(NULL,`20TRUE,`20FALSE,`20NULL); X`09if`20(read_olap->hEvent`20==`20NULL X`09`20`7C`7C`20!ResetEvent(read_olap->hEvent)) X`09`09return`20GetLastError(); X X`09/*`20set`20up`20for`20overlapped`20non-blocking`20I/O`20*/ X X`09tmo.ReadIntervalTimeout`20=`200`20; X`09tmo.ReadTotalTimeoutMultiplier`20=`200`20; X`09tmo.ReadTotalTimeoutConstant`20=`200`20; X`09tmo.WriteTotalTimeoutMultiplier`20=`200`20; X`09tmo.WriteTotalTimeoutConstant`20=`205000`20; X X`09SetCommTimeouts(*port_handle,`20`26tmo); X X`09/*`20get`20the`20current`20state`20of`20the`20port`20so`20we`20can`20modify V`20it`20and X`09`20*`20restore`20it`20*/ X X`09status`20=`20GetCommState(*port_handle,`20`26Dcb_old); X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20GetCommState()`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09/*`20specify`20our`20changes`20*/ X X`09dcb_new`20=`20Dcb_old; X`09dcb_new.BaudRate`20=`209600; X`09dcb_new.ByteSize`20=`208; X`09dcb_new.Parity`20=`20NOPARITY; X`09dcb_new.StopBits`20=`20ONESTOPBIT; X X`09status`20=`20SetCommState(*port_handle,`20`26dcb_new); X X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20SetCommState()`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09return`20NO_ERROR; X`7D X Xclose_the_port(HANDLE`20*port_handle) X`7B X`09BOOL`09status; X X`09/*`20restore`20the`20port`20*/ X X`09status`20=`20SetCommState(*port_handle,`20`26Dcb_old); X X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20SetCommState()`5Cn"); X`20`09`09return`20EXIT_FAILURE; X`09`7D X X`09status`20=`20CloseHandle(*port_handle); X`09if`20(!status)`20`7B X`09`09printf("Error`20from`20CloseHandle()`20on`20comm`20port`5Cn"); X`09`09return`20EXIT_FAILURE; X`09`7D X X`09return`20NO_ERROR; X`7D X X`0C X Xconsole2.h X Xopen_the_console(HANDLE`20*write_handle,`20HANDLE`20*read_handle); X X`0C X Xconsole2.c X X#include`20 X#include`20 X#include`20 X#include`20"console2.h" X Xopen_the_console(HANDLE`20*write_handle,`20HANDLE`20*read_handle) X`7B X`09*write_handle`20=`20GetStdHandle(STD_OUTPUT_HANDLE); X`09if`20(*write_handle`20==`20INVALID_HANDLE_VALUE) X`09`09return`20GetLastError(); X X`09SetConsoleMode(*write_handle,`200); X X`09*read_handle`20=`20GetStdHandle(STD_INPUT_HANDLE); X`09if`20(*read_handle`20==`20INVALID_HANDLE_VALUE) X`09`09return`20GetLastError(); X X`09SetConsoleMode(*read_handle,`200); X X`09return`20NO_ERROR; X`7D X X X`0C X Xmthread2.mak,`20the`20make`20file`20for`20mthread2 X X#`20Microsoft`20Visual`20C++`20generated`20build`20script`20-`20Do`20not`20mod Vify X XPROJ`20=`20MTHREAD2 XDEBUG`20=`201 XPROGTYPE`20=`202 XCALLER`20=`20 XARGS`20=`20 XDLLS`20=`20 XORIGIN`20=`20MSVCNT XORIGIN_VER`20=`201.00 XPROJPATH`20=`20C:`5CTFR`5CARTICLES31-JAN-94`2009:06:28SJ`5CMTHREAD1`5C`20 XUSEMFC`20=`200 XCC`20=`20cl XCPP`20=`20cl XCXX`20=`20cl XCCREATEPCHFLAG`20=`20 XCPPCREATEPCHFLAG`20=`20 XCUSEPCHFLAG`20=`20 XCPPUSEPCHFLAG`20=`20 XFIRSTC`20=`20MTHREAD2.C XFIRSTCPP`20=`20 XRC`20=`20rc XCFLAGS_D_DEXE32`20=`20/nologo`20/W3`20/Zi`20/YX`20/D`20"_X86_"`20/D`20"_DEBUG" V`20/D`20"_CONSOLE"`20/FR X/MD`20/Fd"MTHREAD2.PDB"`20/Fp"MTHREAD2.PCH" XCFLAGS_R_DEXE32`20=`20/nologo`20/W3`20/YX`20/O2`20/D`20"_X86_"`20/D`20"NDEBUG" V`20/D`20"_CONSOLE"`20/FR X/ML`20/Fp"MTHREAD2.PCH" XLFLAGS_D_DEXE32`20=`20/NOLOGO`20/DEBUG`20/DEBUGTYPE:cv`20/SUBSYSTEM:console`20 Vnetapi32.lib XLFLAGS_R_DEXE32`20=`20/NOLOGO`20/SUBSYSTEM:console`20netapi32.lib XLFLAGS_D_LIB32`20=`20/NOLOGO XLFLAGS_R_LIB32`20=`20/NOLOGO XLIBS_D_DEXE32`20=`20 XLIBS_R_DEXE32`20=`20 XRCFLAGS32`20=`20 XD_RCDEFINES32`20=`20-d_DEBUG XR_RCDEFINES32`20=`20-dNDEBUG XOBJS_EXT`20=`20 XLIBS_EXT`20=`20 X!if`20"$(DEBUG)"`20==`20"1" XCFLAGS`20=`20$(CFLAGS_D_DEXE32) XLFLAGS`20=`20$(LFLAGS_D_DEXE32) XLIBS`20=`20$(LIBS_D_DEXE32) XLFLAGS_LIB=$(LFLAGS_D_LIB32) XMAPFILE_OPTION`20=`20 XRCDEFINES`20=`20$(D_RCDEFINES32) X!else XCFLAGS`20=`20$(CFLAGS_R_DEXE32) XLFLAGS`20=`20$(LFLAGS_R_DEXE32) XLIBS`20=`20$(LIBS_R_DEXE32) XMAPFILE_OPTION`20=`20 XLFLAGS_LIB=$(LFLAGS_R_LIB32) XRCDEFINES`20=`20$(R_RCDEFINES32) X!endif XSBRS`20=`20MTHREAD2.SBR`20`5C X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20ABSQUE.SBR`20`5C X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20COMPORT2.SBR`20`5C X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20CONSOLE2.SBR X X XMTHREAD2_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cabsque.h`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Ccomport2.h`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cconsole2.h X X XABSQUE_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cabsque.h X X XCOMPORT2_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Ccomport2.h X X XCONSOLE2_DEP`20=`20`20`5C X`20`20`20`20`20`20`20`20c:`5Ctfr`5Carticles31-JAN-94`2009:06:28sj`5Cmthread1 V`5Cconsole2.h X X Xall:`20`20`20`20$(PROJ).EXE`20$(PROJ).BSC X XMTHREAD2.OBJ:`20`20`20MTHREAD2.C`20$(MTHREAD2_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CCREATEPCHFLAG)`20/c`20MTHREAD2. VC X XABSQUE.OBJ:`20`20`20`20`20ABSQUE.C`20$(ABSQUE_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CUSEPCHFLAG)`20/c`20ABSQUE.C X XCOMPORT2.OBJ:`20`20`20COMPORT2.C`20$(COMPORT2_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CUSEPCHFLAG)`20/c`20COMPORT2.C X XCONSOLE2.OBJ:`20`20`20CONSOLE2.C`20$(CONSOLE2_DEP) X`20`20`20`20`20`20`20`20$(CC)`20$(CFLAGS)`20$(CUSEPCHFLAG)`20/c`20CONSOLE2.C X X$(PROJ).EXE:`20`20`20`20MTHREAD2.OBJ`20ABSQUE.OBJ`20COMPORT2.OBJ`20CONSOLE2.OB VJ`20$(OBJS_EXT) X$(LIBS_EXT) X`20`20`20`20`20`20`20`20echo`20>NUL`20@<<$(PROJ).CRF XMTHREAD2.OBJ`20 XABSQUE.OBJ`20 XCOMPORT2.OBJ`20 XCONSOLE2.OBJ`20 X$(OBJS_EXT) X-OUT:$(PROJ).EXE X$(MAPFILE_OPTION) X$(LIBS) X$(LIBS_EXT) X$(DEFFILE_OPTION)`20-implib:$(PROJ).lib X<< X`20`20`20`20`20`20`20`20link`20$(LFLAGS)`20@$(PROJ).CRF X Xrun:`20$(PROJ).EXE X`20`20`20`20`20`20`20`20$(PROJ)`20$(RUNFLAGS) X X X$(PROJ).BSC:`20$(SBRS) X`20`20`20`20`20`20`20`20bscmake`20@<< X/o$@`20$(SBRS) X<< $ call unpack THREAD.DSJ;1 236909318 "" 37 1 1 $ v=f$verify(v) $ exit