DIRECTORY EditNotify, TiogaNode, TiogaNodeOps; EditNotifyImpl: CEDAR MONITOR EXPORTS EditNotify = BEGIN OPEN EditNotify; NotifyList: TYPE = REF NotifyListBody; NotifyListBody: TYPE = RECORD [ next: NotifyList, action: EditNotifyProc, changeSet: ChangeSet ]; NotifyArray: TYPE = ARRAY Priority OF NotifyList; beforeProcs: NotifyArray; afterProcs: NotifyArray; unlocked: CONDITION; lockCount: INTEGER _ 0; Lock: ENTRY PROC = { lockCount _ lockCount+1 }; Unlock: ENTRY PROC = { IF (lockCount _ lockCount-1) <= 0 THEN { lockCount _ 0; BROADCAST unlocked }}; AddNotifyProc: PUBLIC ENTRY PROC [ proc: EditNotifyProc, time: When _ after, priority: Priority _ normal, changeSet: ChangeSet _ defaultChangeSet] = { ENABLE UNWIND => NULL; WHILE lockCount > 0 DO WAIT unlocked; ENDLOOP; RemoveNotify[proc, time]; IF time=before THEN beforeProcs[priority] _ NEW[NotifyListBody _ [beforeProcs[priority], proc, changeSet]] ELSE afterProcs[priority] _ NEW[NotifyListBody _ [afterProcs[priority], proc, changeSet]]}; RemoveNotifyProc: PUBLIC ENTRY PROC [proc: EditNotifyProc, time: When _ after] = { ENABLE UNWIND => NULL; WHILE lockCount > 0 DO WAIT unlocked; ENDLOOP; RemoveNotify[proc, time] }; RemoveNotify: PROC [proc: EditNotifyProc, time: When _ after] = { FOR p:Priority IN Priority DO prev: NotifyList _ NIL; list: NotifyList _ IF time=before THEN beforeProcs[p] ELSE afterProcs[p]; IF list=NIL THEN LOOP; UNTIL list=NIL DO IF list.action = proc THEN EXIT; prev _ list; list _ list.next; REPEAT FINISHED => LOOP; -- proc not found on this list ENDLOOP; IF prev#NIL THEN prev.next _ list.next ELSE IF time=before THEN beforeProcs[p] _ list.next ELSE afterProcs[p] _ list.next; ENDLOOP }; Notify: PUBLIC PROC [change: REF READONLY Change, time: When] = { ENABLE UNWIND => Unlock[]; kind: OfChange; IF change=NIL THEN RETURN; kind _ change.kind; Lock[]; FOR p:Priority IN Priority DO FOR lst:NotifyList _ GetList[p,time], lst.next UNTIL lst=NIL DO IF lst.changeSet[kind] THEN lst.action[change]; ENDLOOP; ENDLOOP; Unlock[] }; GetList: PROC [p:Priority, time:When] RETURNS [NotifyList] = INLINE { RETURN [IF time=before THEN beforeProcs[p] ELSE afterProcs[p]] }; END.  EditNotifyImpl.mesa; written by Bill Paxton, March 1981 edited by McGregor, February 8, 1983 11:33 am edited by Bill Paxton, June 1, 1983 11:34 am **** Notification Operations **** remove proc from list of notification procedures call notification procedures Êf˜Jšœ7™7Jšœ-™-Jšœ,™,J˜šÏk ˜ J˜ J˜ J˜ —J˜Jš œ œœ œœ ˜IJ˜Jšœ œœ˜&šœœœ˜J˜J˜J˜—Jšœ œœ œ ˜1J˜J˜J˜Jšœ!™!J˜Jšœ œ˜J˜Jšœ œ˜J˜JšÏnœœœ˜/J˜šžœœœ˜Jšœ œ œ ˜N—J˜šž œœœœ˜"J˜J˜J˜J˜,Jšœœœ˜Jšœœœ œ˜.J˜šœ ˜Jšœœ;˜V—šœœ<˜[J˜——šžœœœ˜#J˜.Jšœ0™0Jšœœœ˜Jšœœœ œ˜.J˜J˜—šž œ˜J˜.šœ œ ˜Jšœœ˜šœœ œ˜5Jšœ˜—Jšœœœœ˜šœœ˜Jšœœœ˜ J˜JšœœœÏc˜7Jšœ˜—Jšœœœ˜&Jšœœ œ˜3Jšœ˜Jšœ˜ J˜——š žœœœ œœ˜AJšœ™Jšœœ ˜J˜Jšœœœœ˜J˜J˜šœ œ ˜šœ,œœ˜?Jšœœ˜/Jšœ˜—Jšœ˜—šœ ˜ J˜——šžœœœ˜CJš œœœ œœ˜CJ˜—Jšœ˜J˜—…—| ì