-- File: PupListeners.mesa - last edit: -- AOF 17-Feb-88 15:22:39 -- SMA 1-Sep-83 20:56:59 -- Copyright (C) 1983, 1986, 1988 by Xerox Corporation. All rights reserved. DIRECTORY Process USING [Detach], Runtime USING [GlobalFrame], Stream USING [Handle], PrincOpsMinus USING [NewSelf], PupRouterDefs USING [GetFirstPupSocket, PupRouterSocket], PupPktDefs USING [PupPktStreamMake, PupPktStream], PupStream USING [ PupByteStreamMake, PupListener, PupListenerObject, RejectThisRequest], PupDefs USING [ PupAddress, PupBuffer, PupSocketID, Tocks, PupRouterSendThis, SendErrorPup, SwapPupSourceAndDest, PupSocket, PupSocketMake, ReturnBuffer, PupSocketKick, PupSocketDestroy, veryLongWait, SetPupContentsBytes, AppendStringBodyToPupBuffer], PupTypes USING [fillInPupAddress]; PupListeners: MONITOR IMPORTS Runtime, PrincOpsMinus, Process, PupRouterDefs, PupPktDefs, PupStream, PupDefs EXPORTS PupPktDefs, PupStream = BEGIN OPEN PupRouterDefs, PupDefs; -- Manager data Listen: PROCEDURE [local: PupSocketID] ¬ RealListen; -- The procedure variable for getting linkage to the instance's RealListen. free: LONG POINTER TO FRAME[PupListeners] ¬ LOOPHOLE[Runtime.GlobalFrame[LOOPHOLE[Listen]]]; GetInstance: ENTRY PROCEDURE RETURNS [him: LONG POINTER TO FRAME[PupListeners]] = BEGIN IF free = NIL THEN BEGIN him ¬ --NEW PupListeners-- PrincOpsMinus.NewSelf[]; START him; -- Do initialization code RETURN; END; him ¬ free; free ¬ free.next; END; FreeInstance: ENTRY PROCEDURE [him: LONG POINTER TO FRAME[PupListeners]] = BEGIN him.next ¬ free; free ¬ him; END; next: LONG POINTER TO FRAME[PupListeners] ¬ NIL; myPupListener: PupStream.PupListenerObject ¬ LOOPHOLE[Listen]; socket: PupSocket; timeout: Tocks; stop: BOOLEAN; proc: PROCESS; who: PROCEDURE [LONG UNSPECIFIED, PupAddress]; check: PROCEDURE [PupAddress]; Kind: TYPE = {pkt, byte}; kind: Kind; DontReject: PUBLIC PROCEDURE [PupAddress] = BEGIN END; CreatePupByteStreamListener: PUBLIC PROCEDURE [ local: PupSocketID, proc: PROCEDURE [Stream.Handle, PupAddress], ticks: Tocks, filter: PROCEDURE [PupAddress]] RETURNS [PupStream.PupListener] = BEGIN RETURN[CreatePupListener[local, proc, ticks, byte, filter]]; END; CreatePupPktStreamListener: PUBLIC PROCEDURE [ local: PupSocketID, proc: PROCEDURE [PupPktDefs.PupPktStream, PupAddress], ticks: Tocks, filter: PROCEDURE [PupAddress]] RETURNS [PupStream.PupListener] = BEGIN RETURN[CreatePupListener[local, proc, ticks, pkt, filter]]; END; CreatePupListener: PROCEDURE [ local: PupSocketID, w: PROCEDURE [UNSPECIFIED, PupAddress], ticks: Tocks, k: Kind, f: PROCEDURE [PupAddress]] RETURNS [PupStream.PupListener] = BEGIN him: LONG POINTER TO FRAME[PupListeners] ¬ GetInstance[]; him.socket ¬ PupSocketMake[local, PupTypes.fillInPupAddress, veryLongWait]; him.kind ¬ k; him.who ¬ w; him.check ¬ f; him.timeout ¬ ticks; him.stop ¬ FALSE; him.proc ¬ FORK him.Listen[local]; RETURN[@him.myPupListener]; END; DestroyPupListener: PUBLIC PROCEDURE [listener: PupStream.PupListener] = BEGIN him: LONG POINTER TO FRAME[PupListeners] ¬ LOOPHOLE[Runtime.GlobalFrame[ LOOPHOLE[listener­]]]; him.stop ¬ TRUE; PupSocketKick[him.socket]; JOIN him.proc; PupSocketDestroy[him.socket]; FreeInstance[him]; END; RealListen: PROCEDURE [local: PupSocketID] = BEGIN soc: PupRouterSocket; arg: LONG UNSPECIFIED; b: PupBuffer; UNTIL stop DO b ¬ socket.get[]; IF b # NIL THEN BEGIN SELECT b.pup.pupType FROM rfc => BEGIN OPEN PupStream; FOR soc ¬ GetFirstPupSocket[], soc.next UNTIL soc = NIL DO -- check for duplicate IF soc.remote # b.pup.source THEN LOOP; IF soc.id # b.pup.pupID THEN LOOP; b.pup.address ¬ soc.local; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; EXIT; ENDLOOP; IF soc = NIL THEN BEGIN -- not a duplicate, make a new connection him: PupAddress ¬ b.pup.address; check[ him ! PupStream.RejectThisRequest => BEGIN b.pup.pupType ¬ abort; SwapPupSourceAndDest[b]; SetPupContentsBytes[b, 2]; AppendStringBodyToPupBuffer[b, error]; PupRouterSendThis[b]; GOTO Reject; END]; SELECT kind FROM pkt => arg ¬ PupPktDefs.PupPktStreamMake[ local, him, timeout, alreadyOpened, b.pup.pupID]; byte => arg ¬ PupStream.PupByteStreamMake[ local, him, timeout, alreadyOpened, b.pup.pupID]; ENDCASE => ERROR; PupDefs.ReturnBuffer[b]; Process.Detach[FORK who[arg, him]]; END; EXITS Reject => NULL; END; echoMe => BEGIN b.pup.pupType ¬ iAmEcho; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; END; ENDCASE => SendErrorPup[b, LOOPHOLE[100B], "RFC expected"L]; END; ENDLOOP; END; END. LOG 19-May-83 9:59:26 By: SMA Action: Converted to new BufferMgr. 11-Jul-83 17:17:36 By: SMA Action: Changes for 32-bit procs. 1-Sep-83 20:57:12 By: SMA Action: Fixed initialized . 2-Sep-86 14:44:19 By: AOF Action: New Buffer mgmt package. 17-Feb-88 15:22:07 By: AOF Action: Patch for compiler bug NEWing self.