ported StreamConditions, Conditions fixed

This commit is contained in:
Norayr Chilingarian 2013-11-04 15:24:46 +04:00
parent 81e897f416
commit 4c7126816b
3 changed files with 176 additions and 2 deletions

View file

@ -200,7 +200,8 @@ stage6:
$(VOCSTATIC) -sP ulmTimes.Mod
$(VOCSTATIC) -sP ulmClocks.Mod
$(VOCSTATIC) -sP ulmTimers.Mod
#$(VOCSTATIC) -sP ulmConditions.Mod
$(VOCSTATIC) -sP ulmConditions.Mod
$(VOCSTATIC) -sP ulmStreamConditions.Mod
#pow32 libs

View file

@ -142,7 +142,7 @@ MODULE ulmConditions;
gettime*: GetTimeProc;
preconditions*: PreConditionsProc;
END;
Description = POINTER TO DescriptionRec;
Description* = POINTER TO DescriptionRec;
DescriptionRec* =
RECORD
(Objects.ObjectRec)

View file

@ -0,0 +1,173 @@
(* 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: StreamCondi.om,v 1.1 1994/02/22 20:10:24 borchert Exp $
----------------------------------------------------------------------------
$Log: StreamCondi.om,v $
Revision 1.1 1994/02/22 20:10:24 borchert
Initial revision
----------------------------------------------------------------------------
AFB 1/92
----------------------------------------------------------------------------
*)
MODULE ulmStreamConditions;
IMPORT Conditions := ulmConditions, Events := ulmEvents, Priorities := ulmPriorities, RelatedEvents := ulmRelatedEvents, Streams := ulmStreams;
CONST
msgFailed* = 0; (* message was not processed by the implementation *)
invalidOp* = 1; (* operation was not read or write *)
errorcodes* = 2;
TYPE
ErrorEvent* = POINTER TO ErrorEventRec;
ErrorEventRec* =
RECORD
(Events.EventRec)
errorcode*: SHORTINT;
END;
VAR
errormsg*: ARRAY errorcodes OF Events.Message;
error*: Events.EventType;
CONST
read* = 0; write* = 1; (* operations *)
TYPE
Operation* = SHORTINT; (* read or write *)
TYPE
CreateConditionMessage* =
RECORD
(Streams.Message)
(* in-parameters *)
operation*: Operation; (* read or write *)
(* out-parameters *)
condition*: Conditions.Condition; (* return value *)
stream*: Streams.Stream; (* message processed for this stream *)
msgProcessed*: BOOLEAN; (* initially FALSE; has to be set to TRUE *)
END;
TestConditionMessage* =
RECORD
(Streams.Message)
(* in-parameters *)
operation*: Operation; (* read or write *)
errors*: RelatedEvents.Object; (* relate errors to this object *)
(* out-parameters *)
wouldblock*: BOOLEAN;
msgProcessed*: BOOLEAN;
END;
TYPE
Condition = POINTER TO ConditionRec;
ConditionRec =
RECORD
(Conditions.ConditionRec)
stream: Streams.Stream;
operation: Operation;
END;
VAR
domain: Conditions.Domain;
PROCEDURE InitErrorHandling;
BEGIN
Events.Define(error);
Events.SetPriority(error, Priorities.liberrors);
errormsg[msgFailed] :=
"operation not processed by underlying stream implementation";
errormsg[invalidOp] := "invalid operation (read or write expected)";
END InitErrorHandling;
PROCEDURE Error(object: RelatedEvents.Object; errorcode: SHORTINT);
VAR
event: ErrorEvent;
BEGIN
NEW(event); event.type := error; event.message := errormsg[errorcode];
event.errorcode := errorcode;
RelatedEvents.Raise(object, event);
END Error;
PROCEDURE Test(domain: Conditions.Domain; condition: Conditions.Condition;
errors: RelatedEvents.Object) : BOOLEAN;
VAR
msg: TestConditionMessage;
BEGIN
WITH condition: Condition DO
CASE condition.operation OF
| read: IF Streams.InputInBuffer(condition.stream) THEN
RETURN TRUE
END;
| write: IF Streams.OutputWillBeBuffered(condition.stream) THEN
RETURN TRUE
END;
END;
msg.operation := condition.operation;
msg.errors := errors;
msg.wouldblock := TRUE;
msg.msgProcessed := FALSE;
Streams.Send(condition.stream, msg);
IF ~msg.msgProcessed THEN
Error(errors, msgFailed); RETURN FALSE
END;
RETURN ~msg.wouldblock
END;
END Test;
PROCEDURE InitDomain;
VAR
if: Conditions.Interface;
desc: Conditions.Description;
BEGIN
NEW(if); if.test := Test;
NEW(desc); desc.caps := {}; desc.internal := TRUE;
NEW(domain); Conditions.InitDomain(domain, if, desc);
END InitDomain;
PROCEDURE Create*(VAR condition: Conditions.Condition;
s: Streams.Stream; operation: Operation);
(* condition = NIL in error case, eg if the associated
stream implementation does not interpret such messages
*)
VAR
msg: CreateConditionMessage;
newcond: Condition;
BEGIN
IF (operation # read) & (operation # write) THEN
condition := NIL; Error(s, invalidOp); RETURN
END;
msg.operation := operation; msg.condition := NIL;
msg.stream := s; msg.msgProcessed := FALSE;
Streams.Send(s, msg);
IF ~msg.msgProcessed THEN
Error(s, msgFailed); condition := NIL; RETURN
END;
IF (msg.condition # NIL) & (msg.stream = s) THEN
(* underlying implementation has its own domain and
defines it own conditions
*)
condition := msg.condition; RETURN
END;
NEW(newcond); newcond.stream := s; newcond.operation := operation;
Conditions.Init(newcond, domain);
condition := newcond;
END Create;
BEGIN
InitErrorHandling;
InitDomain;
END ulmStreamConditions.