[comp.lang.modula3] help wanted with Thread.Alert

nr@Princeton.EDU (Norman Ramsey) (04/04/91)

I don't understand why my thread isn't raising Thread.Alerted in the
following program:

  MODULE Alert EXPORTS Main;
  IMPORT Rd, Wr, Thread, Fmt;
  FROM Stdio IMPORT stdin, stdout;
  
  PROCEDURE Copy(cl:Thread.Closure):REFANY RAISES {} =
  VAR result := NEW(REF INTEGER);
  BEGIN
    result^ := 0;
    TRY
      LOOP
        WITH line = Rd.GetLine(stdin) DO
  	INC(result^);
          Wr.PutText(stdout,Fmt.F("line is `%s\'\n",line));
        END;
      END;
    EXCEPT Thread.Alerted => Wr.PutText(stdout,"Alert!\n");
    | Rd.EndOfFile => Wr.PutText(stdout,"EOT\n");
    END;
    RETURN result;
  END Copy;
  
  VAR t := Thread.Fork(NEW(Thread.Closure, apply := Copy));
  
  BEGIN
    Thread.Alert(t);
    Wr.PutText(stdout,"Thread has been alerted.\n");
    Wr.PutText(stdout,Fmt.F("Read %s lines\n",
                            Fmt.Int(NARROW(Thread.Join(t),REF INTEGER)^)));
  END Alert.
  
Here's some output:
nr@hart (44) % a.out
Thread has been alerted.
one
line is `one'
two
line is `two'
three
line is `three'
EOT
Read 3 lines


Can anybody help me understand this behavior?  I have a much larger,
more complicated program that's getting hung on exit because there's a
thread lingering around trying to read stdin and I can't successfully
alert the thread.
-- 
Norman Ramsey
nr@princeton.edu

modula-3@uni-paderborn.de (Thomas Roemke) (04/04/91)

nr@@Princeton.EDU (Norman Ramsey) writes:

>I don't understand why my thread isn't raising Thread.Alerted in the
>following program:
>[..] see below.

Thread.Alert(t) marks t as alerted, nothing else. No
exception is raised, neither in the calling nor in the
marked thread. If you want to have that behaviour, you've
to raise an exception explicitly, e.g. 


  MODULE Alert EXPORTS Main;
  IMPORT Rd, Wr, Thread, Fmt;
  FROM Stdio IMPORT stdin, stdout;
  
  PROCEDURE Copy(cl:Thread.Closure):REFANY RAISES {} =
  VAR result := NEW(REF INTEGER);
  BEGIN
    result^ := 0;
    TRY
      LOOP
        IF Thread.TestAlert() THEN 
	  EXIT; (* or RAISE Thread.Alerted *) 
	END;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	WITH line = Rd.GetLine(stdin) DO
  	INC(result^);
          Wr.PutText(stdout,Fmt.F("line is `%s\'\n",line));
        END;
      END;
    EXCEPT 
      Thread.Alerted => Wr.PutText(stdout,"Alert!\n");
    | Rd.EndOfFile => Wr.PutText(stdout,"EOT\n");
    END;
    RETURN result;
  END Copy;
  
  VAR t := Thread.Fork(NEW(Thread.Closure, apply := Copy));
  
  BEGIN
    Thread.Alert(t);
    Wr.PutText(stdout,"Thread has been alerted.\n");
    Wr.PutText(stdout,Fmt.F("Read %s lines\n",
                            Fmt.Int(NARROW(Thread.Join(t),REF INTEGER)^)));
  END Alert.
  

  However, there's possibly a true bug left (SRC 1.6 SPARC). Using 
  Thread.AlertJoin(t) instead of of Thread.Join(t) has to raise 
  Thread.Alerted, since t is an alerted thread, but nothing happens.....


      
  Thomas



-- 
(*	Thomas Roemke, University of Paderborn, Germany 
	modula-3@uni-paderborn.de
	..!uunet!mcsun!unido!pbinfo!modula-3	*)

nr@hart.Princeton.EDU (Norman Ramsey) (04/05/91)

In article <9104041502.AA04492@thor.uni-paderborn.de> modula-3@uni-paderborn.de (Thomas Roemke) writes:
> Thread.Alert(t) marks t as alerted, nothing else. No
> exception is raised, neither in the calling nor in the
> marked thread. 

Well, no, that's not the way it's supposed to work.  From the Rd
interface:

(*
Many operations on a reader can wait indefinitely.  For example,
GetChar can wait if the user is not typing. In general these waits are
alertable, so each procedure that might wait includes Thread.Alerted
in its RAISES clause. *)

PROCEDURE GetLine(rd: T): TEXT RAISES {EndOfFile, Failure, Alerted, Error};
                                                           ^^^^^^^
-- 
Norman Ramsey
nr@princeton.edu

modula-3@uni-paderborn.de (Thomas Roemke) (04/05/91)

nr@hart.Princeton.EDU (Norman Ramsey) writes:

>Well, no, that's not the way it's supposed to work.  From the Rd
>interface:

>(*
>Many operations on a reader can wait indefinitely.  For example,
>GetChar can wait if the user is not typing. In general these waits are
>alertable, so each procedure that might wait includes Thread.Alerted
>in its RAISES clause. *)

>PROCEDURE GetLine(rd: T): TEXT RAISES {EndOfFile, Failure, Alerted, Error};
>                                                           ^^^^^^^

Oops. Sorry Norman. My answer was a result of misunderstanding your question.
I answered to 'Why isn't t (automatically) raising Thread.Alerted ?' and your 
question actually was 'Why isn't Rd.GetLine raising it ?'.

Thomas


(*	Thomas Roemke, University of Paderborn, Germany 
	modula-3@uni-paderborn.de
	..!uunet!mcsun!unido!pbinfo!modula-3	*)