-- Copyright (C) 1985 by Xerox Corporation. All rights reserved.
-- LogRejection.mesa, HGM, 18-Sep-85 3:37:15
-- This gets called from the Listener process. We can't just print the message because
-- the log might overflow onto a new page. Then we end up deep in the VM machinery,
-- and it might need a Pup Buffer. Buffer lockups have happened.
-- NB: String must not be Local.
DIRECTORY
Heap USING [systemZone],
LogDefs USING [WriteLine, WriteLogEntry],
String USING [AppendDecimal, AppendString],
PupDefs USING [AppendHostName],
PupTypes USING [PupAddress];
LogRejection: MONITOR
IMPORTS Heap, LogDefs, PupDefs, String
EXPORTS LogDefs =
BEGIN
Rejection: TYPE = LONG POINTER TO RejectionRecord;
RejectionRecord: TYPE = RECORD [
next: Rejection,
what: LONG STRING,
who: PupTypes.PupAddress,
count: CARDINAL ];
ready: Rejection ← NIL;
waiting: CONDITION;
printer: PROCESS ← FORK Printer[];
ShowRejection: PUBLIC ENTRY PROCEDURE [what: LONG STRING, who: PupTypes.PupAddress] =
BEGIN
new: Rejection;
FOR finger: Rejection ← ready, finger.next UNTIL finger = NIL DO
IF what = finger.what AND who = finger.who THEN {
finger.count ← finger.count + 1; RETURN; };
ENDLOOP;
new ← Heap.systemZone.NEW[RejectionRecord];
new↑ ← [
next: NIL,
what: what,
who: who,
count: 1 ];
AppendReady[new];
END;
AppendReady: INTERNAL PROCEDURE [rejection: Rejection] =
BEGIN
rejection.next ← NIL;
IF ready = NIL THEN ready ← rejection
ELSE
FOR finger: Rejection ← ready, ready.next DO
IF finger.next = NIL THEN finger.next ← rejection; EXIT;
ENDLOOP;
NOTIFY waiting;
END;
GetReady: ENTRY PROCEDURE RETURNS [rejection: Rejection] =
BEGIN
UNTIL ready # NIL DO WAIT waiting; ENDLOOP;
rejection ← ready;
ready ← ready.next;
END;
Printer: PROCEDURE =
BEGIN
DO
rejection: Rejection ← GetReady[];
log: LONG STRING ← Heap.systemZone.NEW[StringBody[500]];
String.AppendString[log, "Rejecting "L];
String.AppendString[log, rejection.what];
String.AppendString[log, " connection from "L];
PupDefs.AppendHostName[log, rejection.who];
IF rejection.count # 1 THEN {
String.AppendString[log, " count = "L];
String.AppendDecimal[log, rejection.count]; };
LogDefs.WriteLogEntry[log];
LogDefs.WriteLine[log];
Heap.systemZone.FREE[@rejection];
Heap.systemZone.FREE[@log];
ENDLOOP;
END;
END.