AsynchronousEventsImpl.mesa
Copyright Ó 1991 by Xerox Corporation. All rights reserved.
Chauser, September 13, 1991 2:10 pm PDT
Willie-s, September 23, 1991 4:52 pm PDT
~
BEGIN
OPEN USignal: UnixTypes;
UnixSignal: TYPE ~ USignal.Signal;
Event: TYPE ~ AsynchronousEvents.Event;
EventToSig: ARRAY Event OF UnixSignal = [ SIGHUP, SIGINT, SIGPIPE, SIGSTOP, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGLOST, SIGUSR2 ];
ProcessEventPair:
TYPE =
RECORD [
process: PROCESS,
event: Event
];
Registrations:
TYPE =
RECORD [
nRegistrations: CARD ¬ 0,
s: SEQUENCE maxRegistrations: CARD OF ProcessEventPair
];
registrations: REF Registrations ¬ NEW[ Registrations[10] ];
RegisterInterest:
PUBLIC ENTRY
PROC [event: Event, interested:
BOOL] ~ {
self: PROCESS ¬ Process.GetCurrent[];
IF Ok[event, interested, self] THEN RETURN;
assert: interested
IF registrations.nRegistrations = registrations.maxRegistrations THEN MoreRegistrations[];
FOR i:
CARD
IN [0..registrations.maxRegistrations)
DO
IF registrations[i].process =
NIL
THEN {
registrations[i].process ¬ self;
registrations[i].event ¬ event;
registrations.nRegistrations ¬ registrations.nRegistrations.SUCC;
TellPCR[EventToSig[event]];
RETURN;
};
ENDLOOP;
ERROR;
};
TellPCR:
PROC [sig: UnixSignal] ~ {
IF sig = SIGINT THEN UIORegisterInterestInINTEvent[TRUE] ELSE UIORegisterInterestInEvent[sig, TRUE]; -- PCR botch; UIORegisterInterestInEvent doesn't support SIGINT
};
UIORegisterInterestInINTEvent:
PROC[
BOOL ] ~
TRUSTED
MACHINE
CODE {
"XR←UIORegisterInterestInINTEvent"
};
UIORegisterInterestInEvent:
PROC[ UnixSignal,
BOOL ] ~
TRUSTED
MACHINE
CODE {
"XR←UIORegisterInterestInEvent"
};
Ok:
PROC [event: Event, interested:
BOOL, process:
PROCESS]
RETURNS [
BOOL] ~ {
FOR i:
CARD
IN [0..registrations.maxRegistrations)
DO
IF registrations[i].process = process
AND registrations[i].event = event
THEN {
IF
NOT interested
THEN {
registrations[i].process ¬ NIL;
registrations.nRegistrations ¬ registrations.nRegistrations.PRED;
};
RETURN[ TRUE ];
};
ENDLOOP;
RETURN [ NOT interested ];
};
MoreRegistrations:
PROC ~ {
newRegistrations: REF Registrations ¬ NEW[ Registrations[registrations.maxRegistrations+10] ];
newRegistrations.nRegistrations ¬ registrations.nRegistrations;
FOR i:
CARD
IN [0..registrations.maxRegistrations)
DO
newRegistrations[i] ¬ registrations[i];
ENDLOOP;
registrations ¬ newRegistrations;
};
UIOEvent:
TYPE ~
RECORD [
must match record declared in UIOEvents.h
seqNum: CARD,
iopIndex: CARD,
id: UnixSignal,
info: REF
];
continue: BOOL ¬ TRUE;
StopProcessingEvents:
PROC ~ {
continue ¬ FALSE;
};
ProcessEvents:
PROC ~
TRUSTED {
myEvent: UIOEvent;
WHILE continue
DO
UIOAwaitEvent[@myEvent];
ProcessOneEvent[myEvent];
ENDLOOP;
};
UIOAwaitEvent:
PROC [
POINTER
TO UIOEvent] ~
TRUSTED
MACHINE
CODE {
"XR←UIOAwaitEvent"
};
ProcessOneEvent:
ENTRY
PROC [eventInstance: UIOEvent] ~ {
FOR i:
CARD
IN [0..registrations.maxRegistrations)
DO
IF registrations[i].process #
NIL
AND EventToSig[registrations[i].event] = eventInstance.id
THEN {
IF eventInstance.id #
SIGINT
OR eventInstance.iopIndex = 1
THEN
Process.Abort[registrations[i].process ! Process.InvalidProcess => {
registrations[i].process ¬ NIL;
registrations.nRegistrations ¬ registrations.nRegistrations.PRED;
CONTINUE }];
};
ENDLOOP;
};
TRUSTED { Process.Detach[ FORK ProcessEvents[] ] };