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.