-- File: PupSockets.mesa, Last Edit: HGM October 16, 1979 9:33 PM

-- Copyright Xerox Corporation 1979, 1980

-- This module does
everything connected with an instance of a PupSocket. (Which isn’t very much.) For now, there is no need to get fancy, so we create a new copy of this module for each PupSocket that we make, and UnNew it when we are through with it. A cache of the last few might speed things up if that ever becomes interesting. We could also use ourself as the first PupSocket to save a few words of core.


DIRECTORY
CommUtilDefs: FROM "CommUtilDefs" USING [
GlobalFrame, UnNew, SetTimeout, GetReturnFrame],
PupRouterDefs: FROM "PupRouterDefs" USING [
PupRouterForgetAboutSocket, PupRouterKnowAboutSocket,
routerLock, PupRouterSocketObj
ect],
PupDefs: F
ROM "PupDefs" USING [
GetLocalPupAddress, DequeuePup, PupAddress, PupBuffer,
PupRouterSendThis, PupSocket, PupSocketID, Pair, PupSocketObject,
Tocks, veryLongWait, veryShortWait],
DriverDefs: FROM "DriverDefs" USING [doDebug],
BufferDefs: FROM "BufferDefs",
PupTypes: FROM "PupTypes";

PupSockets: MONITOR LOCKS PupRouterDefs.routerLock
IMPORTS CommUtilDefs, PupRouterDefs, PupDefs
EXPORTS PupRouterDefs, PupDefs
SHARES Buffer
Defs =
BEGIN OPEN PupRouterDefs, PupDefs;


myPupSocket: PupSocketObject ← [ -- data for the client
put: Put,
get: Get,
setRemoteAddress: SetRemoteAd
dress,
getLocalAddress: GetLocalAddress ];

dontWait: BOOLEAN ← FALSE
;

myPupRouterSocket: PupRouterSocketObject;

-- For now,
don’t try to be fancy, just create a copy.
PupSocketMake: PUBLIC PROCEDURE [
local: PupSocketID
, remote: PupAddress, ticks: Tocks, id: Pair]
RETURNS [PupSocket] =
BEGIN
him: POINTER TO FRAME[PupSockets] ← NEW PupSockets;
START him; -- Do initialization code
him.myPupRouterSock
et.local ← GetLocalPupAddress[local,@remote];
h
im.myPupRouterSocket.remote ← remote;
him.myPupRouterSocket.id ← id;
PupRouterKnowAboutSocket[@him.
myPupRouterSocket];
SELECT tic
ks FROM
verySh
ortWait => dontWait ← TRUE;
veryLongWait => NULL;
ENDCASE => CommUtilD
efs.SetTimeout[@him.myPupRouterSocket.ready,ticks];
RET
URN[@him.myPupSocket];
END;

PupSocketKick: PUBLIC ENTRY PROCEDURE [s: PupSocket] =
BEGIN
him: POINTER TO FRAME[PupSockets] ← CommUtilDefs.GlobalFrame[s.put];
NOTIFY him.myPupRouterSocket.ready;
END;

PupSocketDestroy: PUBLIC PROCEDURE [s: PupSocket] =
BEGIN
him: POINTER TO FRAME[PupSockets] ← CommUtilDefs.GlobalFrame[s.put];
PupRouterForgetAboutSocket[@him.myPupRouterS
ocket];
CommUtilDefs.UnNew[him];
END;

Get: ENTRY P
ROCEDURE RETURNS [b: PupBuffer] =
BEGIN
IF ~dontWait AND myPupRouterSocket.input.length=0 THEN
BEGIN ENABLE UNWIND
=> NULL; -- we might get aborted
WAIT myPupRouterSocket.ready;
END;
IF myPupRouterSocket.input.length=0
THEN RETURN[NIL];
b ← PupDefs.DequeuePup[@myPupRouterSocket.input];
IF DriverDefs.doDebug AND b#NIL THEN
b.debug ← CommUt
ilDefs.GetReturnFrame[].accesslink;
END;

Put: PR
OCEDURE [b: PupBuffer] =
BEGIN
b.dest ← my
PupRouterSocket.remote;
b.source.socket ← myPupRouterSocket.lo
cal.socket;
Pu
pRouterSendThis[b];
END;

SetR
emoteAddress: ENTRY PROCEDURE [a: PupAddress] =
BE
GIN
myPupRout
erSocket.remote ← a;
END;


GetLocal
Address: ENTRY PROCEDURE RETURNS [PupAddress] =
BEGIN
RETURN[myPupRouterSocket.local];
END;

-- initialization
END. -- of PupSockets module