-- TeleLoadImpl6.mesa -- Last Modified By L. Stewart On September 7, 1982 10:34 PM DIRECTORY PupDefs, PupTypes, PupStream, Storage, TeleLoad6; TeleLoadImpl6: PROGRAM IMPORTS PupDefs, PupStream, Storage EXPORTS TeleLoad6 = BEGIN OPEN TeleLoad6; MDSZoneRec: TYPE = MACHINE DEPENDENT RECORD [ procs(0:0..15): POINTER TO MDSZoneProcsRec ]; MDSZoneProcsRec: TYPE = MACHINE DEPENDENT RECORD [ alloc(0): PROC [zone: MDSZone, size: CARDINAL] RETURNS [POINTER], dealloc(1): PROC [zone: MDSZone, object: POINTER] ]; myMDSZoneRec: MDSZoneRec ← [procs: @myMDSZoneProcsRec]; myMDSZoneProcsRec: MDSZoneProcsRec ← [alloc: myAlloc, dealloc: myDeAlloc]; GetZone: PUBLIC PROC RETURNS [MDSZone] = { RETURN [LOOPHOLE[@myMDSZoneRec]]; }; myAlloc: PROC [zone: MDSZone, size: CARDINAL] RETURNS [POINTER] = { RETURN [Storage.Node[size]]; }; myDeAlloc: PROC [zone: MDSZone, object: POINTER] = { Storage.Free[object]; }; Start: PUBLIC PROC [hostName: STRING] RETURNS [h: Handle] = { sendHim: PupTypes.PupAddress; sid: PupDefs.PupSocketID; allok: BOOLEAN ← TRUE; PupDefs.PupPackageMake[]; sid ← PupDefs.UniqueLocalPupSocketID[]; sendHim ← [ PupTypes.fillInNetID, PupTypes.fillInHostID, teleSwatSocket]; IF hostName.length = 0 THEN RETURN[NIL]; PupStream.GetPupAddress[@sendHim, hostName ! PupStream.PupNameTrouble => {allok ← FALSE; CONTINUE; }]; IF NOT allok THEN RETURN[NIL]; h ← Storage.Node[SIZE[TLObject]]; IF h = NIL THEN ERROR; h.socket ← PupDefs.PupSocketMake[ local: teleSwatSocket, remote: sendHim, ticks: PupDefs.SecondsToTocks[1]]; IF h.socket = NIL THEN ERROR; h.myID.a ← LOOPHOLE[sid.a, CARDINAL]+LOOPHOLE[sid.b, CARDINAL]; h.myID.b ← 0; h.attempts ← 5; RETURN[h]; }; Stop: PUBLIC PROC [h: Handle] = { IF h=NIL OR h.socket=NIL THEN RETURN; PupDefs.PupSocketDestroy[h.socket]; PupDefs.PupPackageDestroy[]; h.socket ← NIL; Storage.Free[h]; }; Store: PUBLIC PROC [h: Handle, cb: CoreBlock] RETURNS [Result] = { RETURN[GStore[h: h, requestcb: cb, type: coreStoreRequest]]; }; Fetch: PUBLIC PROC [h: Handle, cb: CoreBlock] RETURNS [Result] = { RETURN[GFetch[h: h, requestcb: cb, type: coreFetchRequest]]; }; StoreState: PUBLIC PROC [h: Handle, cb: CoreBlock] RETURNS [Result] = { RETURN[GStore[h: h, requestcb: cb, type: stateStoreRequest]]; }; FetchState: PUBLIC PROC [h: Handle, cb: CoreBlock] RETURNS [Result] = { RETURN[GFetch[h: h, requestcb: cb, type: stateFetchRequest]]; }; GStore: PUBLIC PROC [h: Handle, requestcb: CoreBlock, type: PupTypes.PupType] RETURNS [a: Result] = { b: PupDefs.PupBuffer ← NIL; replycb: CorePkt; IF h=NIL OR h.socket=NIL THEN RETURN[[success: FALSE, attempts: 0]]; NewPupID[h]; a.success ← TRUE; a.attempts ← 0; FOR i: INTEGER IN [1..h.attempts] DO a.attempts ← i; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; b ← PupDefs.GetFreePupBuffer[]; replycb ← LOOPHOLE[@b.pupBody]; replycb.address ← requestcb.address; replycb.count ← requestcb.count; FOR j: CARDINAL IN [0..requestcb.count) DO replycb.data[j] ← requestcb.data[j]; ENDLOOP; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]+((requestcb.count+1)/2)]; b ← Exchange[h, b, type]; IF b=NIL THEN LOOP; replycb ← LOOPHOLE[@b.pupBody]; IF NOT Check[requestcb, replycb] THEN LOOP; EXIT; REPEAT FINISHED => a.success ← FALSE; ENDLOOP; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; }; GFetch: PUBLIC PROC [h: Handle, requestcb: CoreBlock, type: PupTypes.PupType] RETURNS [a: Result] = { b: PupDefs.PupBuffer ← NIL; replycb: CorePkt; IF h=NIL OR h.socket=NIL THEN RETURN[[success: FALSE, attempts: 0]]; NewPupID[h]; a.success ← TRUE; a.attempts ← 0; FOR i: INTEGER IN [1..h.attempts] DO a.attempts ← i; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; b ← PupDefs.GetFreePupBuffer[]; replycb ← LOOPHOLE[@b.pupBody]; replycb.address ← requestcb.address; replycb.count ← requestcb.count; PupDefs.SetPupContentsWords[b, SIZE[CorePktObject]]; b ← Exchange[h, b, type]; IF b=NIL THEN LOOP; replycb ← LOOPHOLE[@b.pupBody]; IF replycb.address # requestcb.address THEN LOOP; IF replycb.count # requestcb.count THEN LOOP; FOR j: CARDINAL IN [0..requestcb.count) DO requestcb.data[j] ← replycb.data[j]; ENDLOOP; EXIT; REPEAT FINISHED => a.success ← FALSE; ENDLOOP; IF b#NIL THEN PupDefs.ReturnFreePupBuffer[b]; }; Exchange: PROC [h: Handle, request: PupDefs.PupBuffer, type: PupTypes.PupType] RETURNS[PupDefs.PupBuffer] = { reply: PupDefs.PupBuffer ← NIL; request.pupID ← h.myID; request.pupType ← type; h.socket.put[request]; DO IF reply#NIL THEN PupDefs.ReturnFreePupBuffer[reply]; reply ← h.socket.get[]; IF reply = NIL THEN RETURN[NIL]; IF reply.pupType # LOOPHOLE[LOOPHOLE[type, CARDINAL]+1] THEN LOOP; IF reply.pupID # h.myID THEN LOOP; RETURN[reply]; ENDLOOP; }; Check: PROC [a: CoreBlock, b: CorePkt] RETURNS [BOOLEAN] = { IF a.address # b.address THEN RETURN[FALSE]; IF a.count # b.count THEN RETURN[FALSE]; FOR i: CARDINAL IN [0..a.count) DO IF a.data[i] # b.data[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; NewPupID: PROC [h: Handle] = { h.myID.b ← h.myID.b + 1; }; END. December 30, 1981 3:14 PM, Stewart, created from AudioSocket.mesa July 20, 1982 10:23 AM, Stewart, Mesa6 July 27, 1982 3:59 PM, Stewart, MDSZone September 7, 1982 10:34 PM, Stewart, added attempt counters