File: PupSockets.mesa
Last Edit: HGM March 14, 1981 11:50 AM
Last Edit: Andrew Birrell June 22, 1983 5:25 pm
DIRECTORY
Process USING [SetTimeout, DisableTimeout],
PrincOpsUtils USING [GlobalFrame],
CommFlags USING [doDebug],
CommUtilDefs USING [EnableAborts, GetReturnFrame],
PupRouterDefs USING [
PupRouterForgetAboutSocket, PupRouterKnowAboutSocket, routerLock,
PupRouterSocketObject],
PupDefs USING [
GetLocalPupAddress, DequeuePup, PupAddress, PupBuffer, PupRouterSendThis,
PupSocket, PupSocketID, Pair, PupSocketObject, Tocks, veryLongWait,
veryShortWait],
BufferDefs,
PupTypes;
PupSockets: MONITOR LOCKS PupRouterDefs.routerLock
IMPORTS Process, PrincOpsUtils, CommUtilDefs, PupRouterDefs, PupDefs
EXPORTS PupRouterDefs, PupDefs
SHARES BufferDefs =
BEGIN OPEN PupRouterDefs, PupDefs;
Manager data
free: POINTER TO FRAME[PupSockets] ← LOOPHOLE[PrincOpsUtils.GlobalFrame[
PupSocketMake]];
GetInstance: ENTRY PROCEDURE RETURNS [him: POINTER TO FRAME[PupSockets]] =
BEGIN
IF free = NIL THEN
BEGIN
him ← NEW PupSockets;
START him; -- Do initialization code
RETURN;
END;
him ← free;
free ← free.next;
END;
FreeInstance: ENTRY PROCEDURE [him: POINTER TO FRAME[PupSockets]] =
BEGIN him.next ← free; free ← him; END;
next: POINTER TO FRAME[PupSockets] ← NIL;
myPupSocket: PupSocket = NEW[PupSocketObject ←
[ -- data for the client
put: Put, get: Get, setRemoteAddress: SetRemoteAddress,
getLocalAddress: GetLocalAddress] ];
dontWait, kick: BOOLEANFALSE;
myPupRouterSocket: PupRouterSocketObject;
PupSocketMake: PUBLIC SAFE PROCEDURE [
local: PupSocketID, remote: PupAddress, ticks: Tocks, id: Pair]
RETURNS [PupSocket] =
TRUSTED BEGIN
him: POINTER TO FRAME[PupSockets] ← GetInstance[];
him.myPupRouterSocket.local ← GetLocalPupAddress[local, remote];
him.myPupRouterSocket.remote ← remote;
him.myPupRouterSocket.id ← id;
him.kick ← FALSE;
PupRouterKnowAboutSocket[@him.myPupRouterSocket];
SELECT ticks FROM
veryShortWait => dontWait ← TRUE;
veryLongWait => Process.DisableTimeout[@him.myPupRouterSocket.ready];
ENDCASE => Process.SetTimeout[@him.myPupRouterSocket.ready, ticks];
CommUtilDefs.EnableAborts[@him.myPupRouterSocket.ready];
RETURN[him.myPupSocket];
END;
PupSocketMakeFull: PUBLIC SAFE PROCEDURE [local, remote: PupAddress, ticks: Tocks]
RETURNS [PupSocket] =
TRUSTED BEGIN
him: POINTER TO FRAME[PupSockets] ← GetInstance[];
We need to check local to verify that it is valid
him.myPupRouterSocket.local ← local;
him.myPupRouterSocket.remote ← remote;
him.myPupRouterSocket.id ← [0,0];
him.kick ← FALSE;
PupRouterKnowAboutSocket[@him.myPupRouterSocket];
SELECT ticks FROM
veryShortWait => dontWait ← TRUE;
veryLongWait => Process.DisableTimeout[@him.myPupRouterSocket.ready];
ENDCASE => Process.SetTimeout[@him.myPupRouterSocket.ready, ticks];
CommUtilDefs.EnableAborts[@him.myPupRouterSocket.ready];
RETURN[him.myPupSocket];
END;
PupSocketKick: PUBLIC ENTRY SAFE PROCEDURE [s: PupSocket] =
TRUSTED BEGIN
him: POINTER TO FRAME[PupSockets] ← LOOPHOLE[PrincOpsUtils.GlobalFrame[s.put]];
kick ← TRUE;
NOTIFY him.myPupRouterSocket.ready;
END;
PupSocketDestroy: PUBLIC SAFE PROCEDURE [s: PupSocket] =
TRUSTED BEGIN
him: POINTER TO FRAME[PupSockets] ← LOOPHOLE[PrincOpsUtils.GlobalFrame[s.put]];
PupRouterForgetAboutSocket[@him.myPupRouterSocket];
FreeInstance[him];
END;
Get: ENTRY SAFE PROCEDURE RETURNS [b: PupBuffer] =
TRUSTED BEGIN
IF ~dontWait AND myPupRouterSocket.input.length = 0 THEN
BEGIN
IF ~kick THEN WAIT myPupRouterSocket.ready [ ! UNWIND => NULL];
END;
kick ← FALSE;
IF myPupRouterSocket.input.length = 0 THEN RETURN[NIL];
b ← PupDefs.DequeuePup[myPupRouterSocket.input];
IF CommFlags.doDebug AND b # NIL THEN
b.debug ← CommUtilDefs.GetReturnFrame[].accesslink;
END;
Put: PROCEDURE [b: PupBuffer] =
BEGIN
b.dest ← myPupRouterSocket.remote;
b.source ← myPupRouterSocket.local;
PupRouterSendThis[b];
END;
SetRemoteAddress: ENTRY SAFE PROCEDURE [a: PupAddress] =
TRUSTED BEGIN myPupRouterSocket.remote ← a; END;
GetLocalAddress: ENTRY SAFE PROCEDURE RETURNS [PupAddress] =
TRUSTED BEGIN RETURN[myPupRouterSocket.local]; END;
initialization
myPupRouterSocket.input ← NEW[BufferDefs.QueueObject];
END.