-- ConnectorImpl.mesa -- last edited 23-Nov-81 16:51:43 DIRECTORY Connector, Scheduler, Process; ConnectorImpl: MONITOR IMPORTS Scheduler, Process EXPORTS Connector = { Node: PUBLIC TYPE = RECORD [ value: REF ANY, cond: CONDITION, max: CARDINAL ← 0, body: SEQUENCE size: [0..LAST[INTEGER]] OF RECORD [ choice: PrivateChoice, ret: CARDINAL, direction: {Up, Down, Change}] ]; PrivateHandle: TYPE = REF Node; ChoiceNode: PUBLIC TYPE = RECORD [ response: CARDINAL, cond: CONDITION]; PrivateChoice: TYPE = REF ChoiceNode; CreateChoice: PUBLIC PROC RETURNS [PrivateChoice] = { choice: PrivateChoice ← NEW[ChoiceNode]; Process.DisableTimeout[@choice.cond]; RETURN[choice]}; RegisterUp: PUBLIC PROC [choice: PrivateChoice, retValue: CARDINAL, port: PrivateHandle] = { index: CARDINAL ← port.max ← port.max+1; port.body[index] ← [choice, retValue, Up]}; GetChoice: PUBLIC ENTRY PROC [choice: PrivateChoice] RETURNS [CARDINAL] = { Scheduler.NotifyQueue[]; WAIT choice.cond; RETURN[choice.response]}; Create: PUBLIC PROC [size: CARDINAL] RETURNS [PrivateHandle] = { RETURN[NEW[Node[size]]]}; Put: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = { -- WF.WF1["Put S:%u ", v]; StuffIt[n, v]; WakeUp[n]; -- Scheduler.StandardDelay[]; Process.Yield[]; -- WF.WF0["Put F "] }; Stuff: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = { -- WF.WF1[" Stuff S:%b ", v]; StuffIt[n, v]; WakeUp[n]; Process.Yield[]; -- WF.WF0[" Stuff F "] }; StuffIt: ENTRY PROC [n: PrivateHandle, v: REF ANY] = { n.value ← v}; Place: PUBLIC PROC [n: PrivateHandle, v: REF ANY] = { StuffIt[n, v]; }; Get: PUBLIC PROC [n: PrivateHandle] RETURNS [ret: REF ANY] = { -- WF.WF0[" Get S "]; ret ← GrabIt[n]; IF ret=NIL THEN ERROR; Process.Yield[] -- Scheduler.StandardDelay[]; -- WF.WF0[" Get F "] }; Grab: PUBLIC ENTRY PROC [n: PrivateHandle] RETURNS [ret: REF ANY] = { -- WF.WF0[" Grab S"]; ret ← n.value; -- WF.WF0[" Grab F "] }; GrabIt: ENTRY PROC [n: PrivateHandle] RETURNS[REF ANY] = { RETURN[n.value]}; GetNew: PUBLIC PROC [n: PrivateHandle, v: BOOLEAN] = { -- WF.WF1[" GetNew S:%b ", v]; Scheduler.StandardDelay[]; GetNewBody[n, v]; -- WF.WF0[" GetNew F"] }; GetNewBody: ENTRY PROC[n: PrivateHandle, v: BOOLEAN] = { Scheduler.NotifyQueue[]; DO WAIT n.cond; IF v=NARROW[n.value, REF BOOLEAN]↑ THEN EXIT; ENDLOOP; Scheduler.IncCurrent[]; }; WakeUp: ENTRY PROC [h: PrivateHandle] = { BROADCAST h.cond}; }.