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
DIRECTORY
AsynchronousEvents,
Process,
UnixTypes;
AsynchronousEventsImpl: CEDAR MONITOR
IMPORTS Process
EXPORTS AsynchronousEvents
~ 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[] ] };
END.