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] = INLINE { RETURN [IF time=before THEN beforeProcs[p] ELSE afterProcs[p]] }; END. ° EditNotifyImpl.mesa Copyright Σ 1985, 1986, 1991 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 Christian Jacobi, May 2, 1989 6:06:30 pm PDT **** Notification Operations **** remove proc from list of notification procedures call notification procedures ΚΏ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ=™HKšœ"™"Kšœ4™4K™(K™,K™,—K˜šΟk ˜ K˜ —K˜KšΠblœžœž˜Kšžœ ˜Kšœžœžœ ˜K˜Kšœ žœžœ˜&šœžœžœ˜K˜K˜K˜K˜—Kšœ žœžœ žœ ˜1K˜K˜K˜Kšœ!™!K˜Kšœ ž œ˜K˜Kšœ žœ˜K˜KšΟnœžœžœ˜/K˜š œžœžœ˜Kšžœ žœž œ ˜N—K˜š  œžœžœžœ˜"K˜K˜K˜K˜,Kšžœžœžœ˜Kšžœžœžœ žœ˜.K˜šžœ ž˜˜Kšžœ;˜>——šžœ˜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˜šžœ žœ ž˜šžœ.žœžœž˜AKšžœžœ˜/Kšžœ˜—Kšžœ˜—šœ ˜ K˜——š œžœžœžœ˜GKšžœžœ žœžœ˜AK˜—Kšžœ˜K˜—…—j Ω