TWOpsImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Christian Le Cocq, June 24, 1987 10:09:02 am PDT
Cong, August 18, 1987 10:34:32 am PDT
DIRECTORY
BridgeFTPOps USING [StoreFile, RetrieveFile],
BridgeSubmit USING [TransferProc, Register],
FSExtras USING [GetWDir],
IO USING [STREAM],
Rope USING [ROPE, Cat],
SymTab USING [Ref, Create, Fetch, Store, Delete],
TerminalIO USING [PutRope, TOS],
TWOps;
~
BEGIN
ROPE: TYPE ~ Rope.ROPE;
host: ROPE ← "Velantia";
remoteDir: ROPE ← "/usr/guest/";
twCmd: ROPE ← "/usr/lecocq/timberwolf/TimberWolfSC ";
nInExt: NAT = 4;
inExt: ARRAY [0..nInExt) OF ROPE ← [".cel", ".net", ".blk", ".par"];
nOutExt: NAT = 3;
outExt: ARRAY [0..nOutExt) OF ROPE ← [".out", ".pl1", ".pl2"];
msgStream: IO.STREAM ← TerminalIO.TOS[];
keyTable: SymTab.Ref ← SymTab.Create[];
Key:
TYPE =
REF KeyRec;
KeyRec:
TYPE =
RECORD [
msg: ROPE,
locked: BOOL ← TRUE,
unlocked: CONDITION
];
Store: BridgeSubmit.TransferProc ~ {
PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
FOR i:
NAT
IN [0..nInExt)
DO
localName : ROPE ← Rope.Cat[wDir, id, inExt[i]];
remoteName: ROPE ← Rope.Cat[remoteDir, id, inExt[i]];
msg ← BridgeFTPOps.StoreFile[s, remoteName, localName, msgStream];
IF msg#NIL THEN { OK[id, msg]; RETURN[msg]};
ENDLOOP;
};
Retrieve: BridgeSubmit.TransferProc ~ {
PROC [id, wDir: ROPE, s: IO.STREAM] RETURNS [msg: ROPE]
FOR i:
NAT
IN [0..nOutExt)
DO
localName : ROPE ← Rope.Cat[wDir, id, outExt[i]];
remoteName: ROPE ← Rope.Cat[remoteDir, id, outExt[i]];
msg ← BridgeFTPOps.RetrieveFile[s, remoteName, localName, msgStream];
IF msg#NIL THEN { OK[id, msg]; RETURN[msg]};
ENDLOOP;
OK[id, NIL];
};
TWIt:
PUBLIC
PROC [id:
ROPE, waitUntilDone:
BOOLEAN ←
FALSE]
RETURNS [msg:
ROPE] ~ {
Description of the procedure.
wDir: ROPE ← FSExtras.GetWDir[];
key: Key ← GetKey[id];
cmd: ROPE ← Rope.Cat[twCmd, id];
IF key=NIL THEN RETURN[Rope.Cat["TWOps -> The rope: '", id, "' is already in use"]];
msg ← BridgeSubmit.Register[host, id, cmd, wDir, Store, Retrieve, NIL, NIL, remoteDir];
IF msg=NIL AND waitUntilDone THEN msg ← WaitForOk[key];
};
GetKey:
PROC [id:
ROPE]
RETURNS[key: Key] ~ {
IF SymTab.Fetch[keyTable, id].found THEN RETURN [NIL];
key ← NEW[KeyRec];
[] ← SymTab.Store[keyTable, id, key];
};
WaitForOk:
ENTRY
PROC [key: Key]
RETURNS [msg:
ROPE] ~ {
ENABLE UNWIND => NULL;
WHILE key.locked DO WAIT key.unlocked ENDLOOP;
RETURN [key.msg];
};
OK:
PROC [id, msg:
ROPE] ~ {
key: Key ← NARROW[SymTab.Fetch[keyTable, id].val];
IF key=NIL THEN RETURN;
[] ← SymTab.Delete[keyTable, id];
key.msg ← msg;
Unlock[key];
};
Unlock:
ENTRY
PROC [key: Key] ~ {
ENABLE UNWIND => NULL;
key.locked ← FALSE;
BROADCAST key.unlocked;
};
TerminalIO.PutRope["TWOps loaded\n"];