-- 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