DIRECTORY EditNotify; 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: ChangeType; 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] = { RETURN [IF time=before THEN beforeProcs[p] ELSE afterProcs[p]] }; END. vEditNotifyImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. written by Bill Paxton, March 1981 last edit by Bill Paxton, October 18, 1982 10:42 am Doug Wyatt, March 3, 1985 4:39:51 pm PST Michael Plass, March 29, 1985 2:31:39 pm PST **** Notification Operations **** remove proc from list of notification procedures call notification procedures Κ’˜codešœ™Kšœ Οmœ1™——šžœ˜Kšžœ<˜?K˜——š œžœžœž˜#K˜.Kšœ0™0Kšžœžœžœ˜Kšžœžœžœ žœ˜.K˜K˜—š  œž˜K˜.šžœ žœ ž˜Kšœžœ˜šœžœ žœ˜5Kšžœ˜—Kšžœžœžœžœ˜šžœžœž˜Kšžœžœžœ˜ K˜KšžœžœžœΟc˜7Kšžœ˜—Kšžœžœžœ˜&Kšžœžœ žœ˜3Kšžœ˜Kšžœ˜ K˜——š  œžœžœ žœžœ˜AKšœ™Kšžœžœ ˜K˜Kšžœžœžœžœ˜K˜K˜šžœ žœ ž˜šžœ,žœžœž˜?Kšžœžœ˜/Kšžœ˜—Kšžœ˜—šœ ˜ K˜——š œžœžœ˜=Kš œžœžœ žœžœ˜CK˜—Kšžœ˜K˜—…—` h