-- /ivy/binding/hickory/hickoryNotifyImpl.mesa
-- implementing the client notification of hickory
-- Last edited by: Binding, August 14, 1984 8:28:23 am PDT
DIRECTORY
Hickory USING [ Event, Reason, NotifyProc],
HickoryNotify,
Process USING [ Detach],
RopeSets USING [ RopeSet]
;
HickoryNotifyImpl:
CEDAR
MONITOR
this is a separate monitor... not locked by the lock defined in HickoryStorage!
IMPORTS Process
EXPORTS HickoryNotify, Hickory
Type declarations
ProcQueueEl:
TYPE =
RECORD [
Proc: Hickory.NotifyProc,
Next: ProcQueue ← NIL
];
ProcQueue: TYPE = REF ProcQueueEl;
Global variables ( protected through monitor)
procQueue: ProcQueue ← NIL;
Operations
RegisterNotifyProc:
PUBLIC
ENTRY
PROCEDURE [ proc: Hickory.NotifyProc] =
BEGIN
here we insert a new procedure into queue.
new: ProcQueue ← NEW[ ProcQueueEl];
new.Proc ← proc;
IF procQueue = NIL THEN procQueue ← new
ELSE
BEGIN
new.Next ← procQueue;
procQueue ← new;
END;
END; -- RegisterNotifyProc
RemoveNotifyProc:
PUBLIC
ENTRY
PROCEDURE [ proc: Hickory.NotifyProc] =
BEGIN
NoOp if not previously registered
prev, cur: ProcQueue;
IF procQueue = NIL THEN RETURN;
prev ← NIL; cur ← procQueue;
WHILE cur #
NIL
AND cur.Proc # proc
DO
prev ← cur; cur ← cur.Next;
ENDLOOP;
IF cur #
NIL
THEN
-- we found the proc!
IF prev =
NIL
THEN
BEGIN
procQueue ← cur;
cur.Next ← NIL;
END
ELSE
BEGIN
prev.Next ← cur.Next;
cur.Next ← NIL;
END;
END; -- RemoveNotifyProc
NotifyClients:
PUBLIC
ENTRY
PROCEDURE [ reason: Hickory.Reason, ev: Hickory.Event, data: RopeSets.RopeSet] =
BEGIN
to fork off a notification process for each registered notify proc.
cur: ProcQueue ← procQueue;
WHILE cur #
NIL
DO
TRUSTED { Process.Detach[ FORK cur.Proc[ reason, ev, data]]};
cur ← cur.Next;
ENDLOOP;
END; -- NotifyProc
END.