-- /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
= BEGIN
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.