(* Ulm's Oberon Library Copyright (C) 1989-1994 by University of Ulm, SAI, D-89069 Ulm, Germany ---------------------------------------------------------------------------- Ulm's Oberon Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Ulm's Oberon Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ---------------------------------------------------------------------------- E-mail contact: oberon@mathematik.uni-ulm.de ---------------------------------------------------------------------------- $Id: Process.om,v 1.3 2004/09/10 16:42:31 borchert Exp $ ---------------------------------------------------------------------------- $Log: Process.om,v $ Revision 1.3 2004/09/10 16:42:31 borchert id and host added Revision 1.2 2004/04/02 17:58:26 borchert softTermination and TerminateSoftly added Revision 1.1 1994/02/22 20:09:43 borchert Initial revision ---------------------------------------------------------------------------- AFB 3/92 ---------------------------------------------------------------------------- *) MODULE ulmProcess; IMPORT Events := ulmEvents, Priorities := ulmPriorities; (* user readable name of our process *) TYPE Name* = ARRAY 128 OF CHAR; VAR name*: Name; id*: Name; (* something that identifies our process on our host *) host*: Name; (* something that identifies our host, may be "" *) (* exit codes *) TYPE ExitCode* = INTEGER; VAR indicateSuccess*: ExitCode; indicateFailure*: ExitCode; (* process events *) TYPE ExitEvent* = POINTER TO ExitEventRec; ExitEventRec* = RECORD (Events.EventRec) exitcode*: ExitCode; END; VAR softTermination*: Events.EventType; termination*: Events.EventType; abort*: Events.EventType; startOfGarbageCollection*, endOfGarbageCollection: Events.EventType; (* these events indicate beginning and end of a garbage collection *) TYPE ExitProc* = PROCEDURE (code: ExitCode); AbortProc* = PROCEDURE; PauseProc* = PROCEDURE; Interface* = POINTER TO InterfaceRec; InterfaceRec* = RECORD exit*: ExitProc; abort*: AbortProc; pause*: PauseProc; END; (* private declarations *) VAR handlers: Interface; nestlevel: INTEGER; PROCEDURE SetHandlers*(if: Interface); BEGIN handlers := if; END SetHandlers; PROCEDURE Exit*(code: ExitCode); VAR event: ExitEvent; BEGIN INC(nestlevel); IF nestlevel = 1 THEN NEW(event); event.type := termination; event.message := "exit"; event.exitcode := code; Events.Raise(event); END; handlers.exit(code); handlers.pause; LOOP END; END Exit; PROCEDURE TerminateSoftly*; VAR event: Events.Event; BEGIN NEW(event); event.type := softTermination; event.message := "terminate, please!"; Events.Raise(event); END TerminateSoftly; PROCEDURE Terminate*; BEGIN Exit(indicateSuccess); END Terminate; PROCEDURE Abort*; VAR event: Events.Event; BEGIN INC(nestlevel); IF nestlevel = 1 THEN NEW(event); event.type := abort; event.message := "abort"; Events.Raise(event); END; handlers.abort; handlers.exit(indicateFailure); handlers.pause; LOOP END; END Abort; PROCEDURE Pause*; BEGIN handlers.pause; END Pause; (* =============================================================== *) PROCEDURE AbortHandler(event: Events.Event); BEGIN Abort; END AbortHandler; (* =============================================================== *) PROCEDURE DummyExit(code: ExitCode); BEGIN LOOP END; END DummyExit; PROCEDURE DummyAbort; BEGIN LOOP END; END DummyAbort; PROCEDURE DummyPause; BEGIN LOOP END; END DummyPause; BEGIN nestlevel := 0; name := "Process.name"; indicateSuccess := 0; indicateFailure := 1; NEW(handlers); handlers.exit := DummyExit; handlers.abort := DummyAbort; handlers.pause := DummyPause; Events.Define(termination); Events.SetPriority(termination, Priorities.exit); Events.Handler(termination, Events.NilHandler); Events.Define(abort); Events.SetPriority(abort, Priorities.exit); Events.Handler(abort, Events.NilHandler); Events.Define(softTermination); Events.SetPriority(softTermination, Priorities.message); Events.Handler(softTermination, Events.NilHandler); Events.AbortHandler(AbortHandler); Events.Define(startOfGarbageCollection); Events.SetPriority(startOfGarbageCollection, Priorities.message); Events.Ignore(startOfGarbageCollection); Events.Define(endOfGarbageCollection); Events.SetPriority(endOfGarbageCollection, Priorities.message); Events.Ignore(endOfGarbageCollection); END ulmProcess.