-- FIFOConnectorBoolImpl.mesa
-- last edited   July 13, 1981  8:26 AM 

DIRECTORY
	Envelopes,
	FIFOConnectorBool,
	FIFOScheduler,
	Process,
	WF;

FIFOConnectorBoolImpl: MONITOR
	IMPORTS FIFOScheduler, Process, WF
	EXPORTS FIFOConnectorBool = { OPEN Envelopes;

New: CONDITION;
value: BOOLEAN;
length: CARDINAL = 6;
index: CARDINAL ← 0;
queue: ARRAY [0..length) OF Envelope;

Put: PUBLIC PROC [v: BOOLEAN] = {
--	WF.WF1["Put S:%b ", v];
	StuffIt[v];
	FIFOScheduler.StandardDelay[];
	Process.Yield[];
--	WF.WF0["Put F "]
	};

Stuff: PUBLIC PROC [v: BOOLEAN] = {
--	WF.WF1["  Stuff S:%b ", v];
	StuffIt[v];
	Process.Yield[];
--	WF.WF0["  Stuff F "]
	};

StuffIt: ENTRY PROC [v: BOOLEAN] = {
	e: Envelope;
	value ← v;
	BROADCAST New;
	WHILE ~EmptyQueue[] DO 
		e ← FirstOfQueue[];
		e.value ← value;
		NOTIFY e.cond↑;
	ENDLOOP};

Get: PUBLIC PROC RETURNS [ret: BOOLEAN] = {
	ret ← GrabIt[];
	FIFOScheduler.StandardDelay[]};

Grab: PUBLIC ENTRY PROC RETURNS [ret: BOOLEAN] = {
--	WF.WF0["      Grab S"];
	ret ← value;
--	WF.WF0["      Grab F "]
	};

GrabIt: ENTRY PROC RETURNS[BOOLEAN] = {
	RETURN[value]};

GetNew: PUBLIC PROC [v: BOOLEAN] = {
--	WF.WF1["        GetNew S:%b ", v];
	GetNewBody[v];
	FIFOScheduler.StandardDelay[];
--	WF.WF0["        GetNew F"]
	};

GetNewBody: ENTRY PROC [v: BOOLEAN] = {
	FIFOScheduler.NotifyQueue[];
	DO
		WAIT New;
		IF v=value THEN EXIT;
		ENDLOOP;
	FIFOScheduler.IncCurrent[];
	};

RequestNew: PUBLIC PROC [e:Envelope] = {
	FIFOScheduler.StandardDelay[];
	PutOnQueue[e]};

EmptyQueue: PROC RETURNS [BOOLEAN] = {
	RETURN[index=0]};

FirstOfQueue: PROC RETURNS [v: Envelope] = {
	v ← queue[index];
	index ← index+1};

PutOnQueue: ENTRY PROC [v: Envelope] = {
	IF index>=length THEN ERROR;
	queue[index← index+1] ← v};

Process.DisableTimeout[@New];

}.