XlFinalizePrivateImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, April 7, 1988 2:01:36 pm PDT
Christian Jacobi, February 3, 1993 11:57 am PST
Willie-s, September 30, 1991 6:17 pm PDT
DIRECTORY
Atom, Xl, XlPrivateTypes, XlFinalizePrivate;
XlFinalizePrivateImpl: CEDAR MONITOR
IMPORTS Atom, Xl
EXPORTS Xl, XlPrivateTypes, XlFinalizePrivate =
BEGIN
ConnectionPrivate: PUBLIC <<Xl>> TYPE = XlPrivateTypes.ConnectionPrivateImplRec;
FinalizationRep: PUBLIC <<XlPrivateTypes>> TYPE = FinalizationRec;
FinalizationRec: TYPE = RECORD [
finalMatch: Xl.Match ¬ NIL,
finalizationTQ: Xl.TQ ¬ NIL,
countList: Atom.PropList ¬ NIL
];
Init: PUBLIC PROC [c: Xl.Connection, finalMatch: Xl.Match ¬ NIL] = {
cPriv: REF XlPrivateTypes.ConnectionPrivateImplRec ¬ c.cPriv;
cPriv.finalizationStuff ¬ NEW[FinalizationRec ¬ [
finalMatch: finalMatch,
finalizationTQ: Xl.CreateTQ[],
countList: Atom.PutPropOnList[NIL, NIL, NEW[CARD ¬ 1]]
]];
};
FinalizationStuff: PROC [c: Xl.Connection] RETURNS [REF FinalizationRec ¬ NIL] = {
IF c#NIL THEN {
cPriv: REF XlPrivateTypes.ConnectionPrivateImplRec ¬ c.cPriv;
IF cPriv#NIL THEN RETURN [cPriv.finalizationStuff];
};
};
IncRefCount: PUBLIC ENTRY PROC [c: Xl.Connection, object: REF ¬ NIL] = {
finalizationStuff: REF FinalizationRec ~ FinalizationStuff[c];
IF finalizationStuff#NIL THEN {
count: REF CARD ¬ NARROW[Atom.GetPropFromList[finalizationStuff.countList, object]];
IF count#NIL
THEN count­ ¬ count­+1
ELSE finalizationStuff.countList ¬ Atom.PutPropOnList[finalizationStuff.countList, object, NEW[CARD ¬ 1]];
};
};
DecRefCount: PUBLIC ENTRY PROC [c: Xl.Connection, object: REF ¬ NIL] = {
finalizationStuff: REF FinalizationRec ~ FinalizationStuff[c];
IF finalizationStuff#NIL THEN {
count: REF CARD ¬ NARROW[Atom.GetPropFromList[finalizationStuff.countList, object]];
IF count#NIL THEN {
IF count­#1
THEN count­ ¬ count­ - 1
ELSE finalizationStuff.countList ¬ Atom.RemPropFromList[finalizationStuff.countList, object];
};
IF finalizationStuff.countList=NIL THEN {
--fork to leave monitor and to be on right tq
tq: Xl.TQ;
finalMatch: Xl.Match ~ finalizationStuff.finalMatch;
IF finalMatch#NIL THEN tq ¬ finalMatch.tq;
IF tq=NIL THEN tq ¬ finalizationStuff.finalizationTQ;
Xl.Enqueue[tq: tq, proc: TryCloseConnection, data: c];
};
};
};
TryCloseConnection: Xl.EventProcType = {
c: Xl.Connection ~ NARROW[clientData];
finalizationStuff: REF FinalizationRec ~ FinalizationStuff[c];
IF finalizationStuff.countList=NIL THEN { 
finalMatch: Xl.Match ~ finalizationStuff.finalMatch;
IF finalMatch#NIL THEN {
proc: Xl.EventProcType ¬ finalMatch.proc;
IF proc#NIL THEN {
event: REF Xl.EventRep.finalEvent ¬ NEW[Xl.EventRep.finalEvent];
event.connection ¬ c;
event.refCountTransition ¬ TRUE;
proc[event, finalMatch.data, tq];
};
};
IF finalizationStuff.countList=NIL THEN Xl.CloseConnection[c];
};
};
END.