comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: Last chance handler on a PC
  2020-01-30 20:02  5%   ` Jeffrey R. Carter
@ 2020-01-30 20:26  0%     ` Niklas Holsti
  0 siblings, 0 replies; 23+ results
From: Niklas Holsti @ 2020-01-30 20:26 UTC (permalink / raw)


On 2020-01-30 22:02, Jeffrey R. Carter wrote:
> On 1/30/20 8:35 PM, ahlan@marriott.org wrote:
>>
>> To catch unhandled exceptions you only need to write a simple 
>> procedure and export it as __gnat_last_chance_handler.
>> This is linked into the program in preference to the default last 
>> chance handler provided by GNAT.
>> This procedure is called if nothing catches a raised exception.
>> Including those raised during package elaboration.
> 
> Doing
> 
> Ada.Task_Termination.Set_Specific_Handler
>     (T       => Ada.Task_Identification.Environment_Task,
>      Handler => Last_Chance'access);
> 
> should do the same thing more portably. It will be called when the 
> environment task terminates for any reason; you would only want it to 
> actually do something when Cause = Unhandled_Exception.

Looks good, but to catch all elaboration-time exceptions (in other 
packages) the package that executes that call, in its own elaboration 
code, must be elaborated before all other packages. Do you have some 
easy way to ensure that, without inserting elaboration pragmas in all 
other packages?

I had a similar elaboration problem some time ago in an embedded 
application, where I wanted to set up some HW error-trap handlers that I 
would like to be active also during elaboration, but I found no easy way 
to ensure that the trap-handling package would be elaborated before all 
other packages.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .


^ permalink raw reply	[relevance 0%]

* Re: Last chance handler on a PC
  @ 2020-01-30 20:02  5%   ` Jeffrey R. Carter
  2020-01-30 20:26  0%     ` Niklas Holsti
  0 siblings, 1 reply; 23+ results
From: Jeffrey R. Carter @ 2020-01-30 20:02 UTC (permalink / raw)


On 1/30/20 8:35 PM, ahlan@marriott.org wrote:
> 
> To catch unhandled exceptions you only need to write a simple procedure and export it as __gnat_last_chance_handler.
> This is linked into the program in preference to the default last chance handler provided by GNAT.
> This procedure is called if nothing catches a raised exception.
> Including those raised during package elaboration.

Doing

Ada.Task_Termination.Set_Specific_Handler
    (T       => Ada.Task_Identification.Environment_Task,
     Handler => Last_Chance'access);

should do the same thing more portably. It will be called when the environment 
task terminates for any reason; you would only want it to actually do something 
when Cause = Unhandled_Exception.

-- 
Jeff Carter
"My mind is a raging torrent, flooded with rivulets of
thought, cascading into a waterfall of creative alternatives."
Blazing Saddles
89


^ permalink raw reply	[relevance 5%]

* timer_server triggers Task_Termination handler
@ 2016-04-21 10:23  7% Per Dalgas Jakobsen
  0 siblings, 0 replies; 23+ results
From: Per Dalgas Jakobsen @ 2016-04-21 10:23 UTC (permalink / raw)


Is it correct behaviour when tasks internal to the GNAT run-time causes 
users task_termination handlers to be called?

This behaviour is seen on:
   1) Debian Linux: gnat-5 (Ada 2005, Ada 2012).
   2) AIX: GNAT Pro 6.1.0w (Ada 2005).

A simple demonstration of the issue:

--------------------------------------------------------------------------------
with Ada.Text_IO;
with Log_Unhandled_Exceptions;

procedure Timer_Server_Noise is

begin
    Ada.Text_IO.Put_Line ("Start of main");

    select
       delay 0.5;
    then abort
       loop
          delay 0.1;
       end loop;
    end select;

    Ada.Text_IO.Put_Line ("End of main");
end  Timer_Server_Noise;
--------------------------------------------------------------------------------
with Ada.Exceptions;
with Ada.Task_Identification;
with Ada.Task_Termination;

package Log_Unhandled_Exceptions is

    pragma Elaborate_Body;

    use Ada.Task_Identification;
    use Ada.Task_Termination;
    use Ada.Exceptions;

    --
    protected Last_Wishes is
       procedure Log_Any_Exit (Cause : in Cause_Of_Termination;
                               T     : in Task_Id;
                               E     : in Exception_Occurrence);
    end;

end Log_Unhandled_Exceptions;
--------------------------------------------------------------------------------
with Ada.Text_IO;


package body Log_Unhandled_Exceptions is

    -- Encapsulates the actual log call
    procedure Log (Text : in String) is
    begin
       Ada.Text_IO.Put_Line ("Log_Unhandled_Exceptions >> " &
                               Text);
    end Log;

    --
    protected body Last_Wishes is

       procedure Log_Any_Exit (Cause : in Cause_Of_Termination;
                               T     : in Task_Id;
                               E     : in Exception_Occurrence) is
       begin
          case Cause is
             when Normal =>
                Log ("Normal exit of task: " & Image (T));
             when Abnormal =>
                Log ("Abnormal exit of task: " & Image (T));
             when Unhandled_Exception =>
                Log ("Unhandled exception in task: " & Image (T));
          end case;
       end Log_Any_Exit;

    end Last_Wishes;


begin
    if Current_Task_Fallback_Handler = null then
       Set_Dependents_Fallback_Handler (Last_Wishes.Log_Any_Exit'Access);
    else
       Log ("Fallback handler already set, will not set own handler.");
    end if;

    if Specific_Handler (Current_Task) = null then
       Set_Specific_Handler (Current_Task, Last_Wishes.Log_Any_Exit'Access);

    else
       Log ("Specific handler already set, will not set own handler.");
    end if;
end Log_Unhandled_Exceptions;
--------------------------------------------------------------------------------

~Per

^ permalink raw reply	[relevance 7%]

* Re: Tasking troubles, unexpected termination.
  2012-10-31  1:05  5%   ` Anh Vo
@ 2012-10-31  2:17  6%     ` Shark8
  0 siblings, 0 replies; 23+ results
From: Shark8 @ 2012-10-31  2:17 UTC (permalink / raw)


Here's the updated code:

---- Scheduling.adb ------------------------------------------
with
Ada.Text_IO,
Ada.Calendar,
Ada.Containers.Indefinite_Vectors,
Ada.Task_Termination,
Ada.Task_Identification,
Task_Debugging;

Procedure Scheduling is

    -- Introduce shorthand so convert Strings to access strings.
    Function "+" (Item : String) Return Not Null Access String is
      ( New String'(Item) );
    
    -- Forward declare the Notification type; indicate it has discriminants.
    Type Notification(<>);
    
    -- Declare Handle for Notifications.
    Type Notification_Handle is Not Null Access Notification;
    
    Type Notification(	Message	: Not Null Access String;
			Expiry	: Not Null Access Ada.Calendar.Time
		     ) is null record;
    
    -- Declare the Timing-task.
    Task Type Timing ( Resolution : Not Null Access Duration ) is
	Entry Add( Event : Notification_Handle );
    end Timing;

    
    -- Implementation for the timing-task.
    Task body Timing is

	-- Package for showing Duration.
	Package Decimal_Display is new Ada.Text_IO.Fixed_IO( Duration );
	
	-- Internal package, defining Vectors holding notification handles.
	Package Notification_Vector is New Ada.Containers.Indefinite_Vectors
	  ( Index_Type => Positive, Element_Type => Notification_Handle );
	Use Notification_Vector;
	
	-- Handle expired messages.
	Procedure Handle_Expiration( List : in out Vector ) is
	    Use Ada.Calendar, Ada.Text_IO;
	    Length : Positive:= Positive(List.Length);
	    Now    : Time:= Clock;

	    -- We flag everything to be deleted, as tampering with the cursor is
	    -- not good.
	    Type Deletion_Flags is Array(1..Length) of Boolean;
	    Deletion_Marks : Deletion_Flags:= (Others => False);
	    
	    
	    procedure Execute(Position : Cursor) is
		Item	: Constant Notification_Handle:= Element(position);
		Index	: Constant Positive:= Positive( To_Index(position) );
	    begin
		Deletion_Marks(Index):= Now >= Item.Expiry.All;
		--
		Ada.Text_IO.Put( ASCII.HT & "Exipration: " );
		Decimal_Display.Put( Item.Expiry.All - Now, Fore => 2, Aft => 3 );
		Ada.Text_IO.New_Line;
	    end Execute;

	begin
	    -- Iterate through the vector's elements; old-style iterator.
	    List.Reverse_Iterate( Process => Execute'Access );

	    -- Delete flagged elements; iteration bckwards to preserve indicies.
	    For Index in reverse Deletion_Marks'Range loop
		if Deletion_Marks(Index) then
		    
		    Put_Line( "Message: " & List(Index).Message.All);
		    List.Delete( Index );
		end if;
	    end loop;
	    
	    -- Render a report on the new length, if it was altered.
	    declare
		Post_op_length : Natural:= Natural(List.Length);
	    begin
		if Length /= post_op_length then
		    Put_Line( "Deleted items; New Length:" &  post_op_length'Img);
		end if;
	    end;
	end Handle_Expiration;

	-- Declare a Vector to hold all the nofifications.
	Notification_List : Vector:= Empty_Vector;
	
	Use Ada.Task_Termination, Task_Debugging, Ada.Containers, Ada.Calendar;
	
	-- Mark the start-time.
	Start : Time:= Clock;
	
--	Function Elapsed Return String is
--	  ( Duration'Image(Clock - Start)(1..7) );
	Function Elapsed Return Duration is
	  ( Clock - Start );

    begin
	-- Set our debugging-handler for this task.
	Ada.Task_Termination.Set_Specific_Handler(
		T       => Ada.Task_Identification.Current_Task,
		Handler => Debug.Termination'Access );

	-- When there are no items in our internal vector, then we need can only
	-- accept Add or terminate the task.
	-- When we add an item, then we can either add another item or when the
	-- time expires iterate the vector and handling Notifications as needed.
	loop
	    select 
		accept Add( Event : Notification_Handle ) do
		    Notification_List.Append( Event );
		end add;
		while not Notification_List.Is_Empty loop
		    Ada.Text_IO.Put( "Elapsed:" );
		    Decimal_Display.Put( Elapsed, Fore => 2, Aft => 3 );
		    Ada.Text_IO.New_Line;
		    Handle_Expiration( List => Notification_List );
		    select
			accept Add( Event : Notification_Handle ) do
			    Notification_List.Append( Event );
			    Ada.Text_IO.Put_Line( "New Length: " & Notification_List.Length'Img );
			    Ada.Text_IO.Put( ASCII.HT & "Exipration: " );
			    Decimal_Display.Put( Event.Expiry.All - Clock, Fore => 2, Aft => 3 );
			    Ada.Text_IO.New_Line;
			end add;
		    or
			delay Timing.Resolution.All;
		    end select;
		end loop;
		Ada.Text_IO.Put_Line( "EMPTY." );
	    or
		terminate;
	    end select;
	end loop;
    end Timing;
    
    
      
    K : Timing( Resolution => New Duration'(2.0) ); -- 2 second resolution.
    Now : Ada.Calendar.Time:= Ada.Calendar.Clock;
begin
    For Index in 1..10 loop
	declare
	    Use Ada.Calendar;
	    Item : Notification(
			 Message => + ("DD"&Positive'Image(Index)),
			 -- Expire at Now and 3*Index seconds.
			 Expiry  => New Time'( Now + Duration(Index) )
			);
	begin
	    K.Add( Event => New Notification'(Item) );
	end;
    end loop;
    
    -- Add an element in the past... it should immediately be operated on.
    K.Add( Event => New Notification'(
	Message => + ("Last."),
	Expiry  => New Ada.Calendar.Time'( Now )
	)
    );

end Scheduling;

---- Task_Debugging.ads ----------------------------------------------
-- The following are not strictly nessacary, but used in this example for 
-- debugging purposes.
With
System.Address_To_Access_Conversions,
Ada.Unchecked_Conversion,
Ada.Exceptions.Traceback,
Ada.Task_Identification,
Ada.Task_Termination;

Package Task_Debugging is
    Pragma Elaborate_Body;
    
    Protected Type Debugging is
	-- Termination debugging function.
	procedure Termination(
				 Cause : Ada.Task_Termination.Cause_Of_Termination;
				 T     : Ada.Task_Identification.Task_Id;
				 X     : Ada.Exceptions.Exception_Occurrence);

    End Debugging;
    
    -- Debug, an instance of our debugging object.
    Debug : Debugging;
    
End Task_Debugging;

---- Task_Debugging.adb ----------------------------------------------
With Ada.Text_IO;

Package Body Task_Debugging is

    Protected body Debugging is
	-- Termination debugging function.
	procedure Termination(
		       Cause : Ada.Task_Termination.Cause_Of_Termination;
		       T     : Ada.Task_Identification.Task_Id;
		       X     : Ada.Exceptions.Exception_Occurrence) is
	    Use Ada.Text_IO, Ada.Task_Termination, Ada.Exceptions;
	begin
	    Put_Line("Termination: "& Cause'Img);
	    case Cause is
	    When Normal | Abnormal => Null;
	    When Unhandled_Exception =>
		Put_Line( Exception_Name(X)&": "&Exception_Message(X) );
	    end case;
	end Termination;	
    end Debugging;

End Task_Debugging;
---------------------------------------------------------------------------

I've fixed the original problems (first the "tampering", and second a constraint_error) but there's still something strange going on. The discriminants for notifications seem to be being ignored (or rather the latest one being used).

Here's the output:
C:\Programming\Projects\Scheduler>scheduling.exe
Elapsed: 0.000
        Exipration:  0.984
New Length:  2
        Exipration:  1.983
Elapsed: 0.002
        Exipration:  1.982
        Exipration:  1.982
New Length:  3
        Exipration:  2.981
Elapsed: 0.004
        Exipration:  2.980
        Exipration:  2.980
        Exipration:  2.980
[...]
Message: Last.
Deleted items; New Length: 10
Elapsed: 2.047
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
        Exipration:  7.938
Elapsed: 4.051
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
        Exipration:  5.933
Elapsed: 6.061
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
        Exipration:  3.923
Elapsed: 8.086
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
        Exipration:  1.898
Elapsed:10.106
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
        Exipration: -0.122
Message: DD 10
Message: DD 9
Message: DD 8
Message: DD 7
Message: DD 6
Message: DD 5
Message: DD 4
Message: DD 3
Message: DD 2
Message: DD 1
Deleted items; New Length: 0
EMPTY.
Termination: NORMAL

As you can see, instead of each element being different they're all tagged as having the same expiration.



^ permalink raw reply	[relevance 6%]

* Re: Tasking troubles, unexpected termination.
  2012-10-30 23:01  5% ` Adam Beneschan
@ 2012-10-31  1:05  5%   ` Anh Vo
  2012-10-31  2:17  6%     ` Shark8
  0 siblings, 1 reply; 23+ results
From: Anh Vo @ 2012-10-31  1:05 UTC (permalink / raw)


On Tuesday, October 30, 2012 4:01:11 PM UTC-7, Adam Beneschan wrote:
> On Tuesday, October 30, 2012 3:03:45 PM UTC-7, Shark8 wrote: > Also, if there is some tasking-exceptions interaction, how do I force them to display [and/or handle them] instead of falling off a cliff? Have you looked into Ada.Task_Termination? (RM C.7.3) That's just the first thought off the top of my head; I haven't looked at your code closely. -- Adam

Using Ada.Task_Termination to monitor the tasks in this program, I got the following results showing task K terminated due unhandled exception PROGRAM_ERROR.

C:\Ada_2005\gps_gpr\Aspect_Programming\scheduling
New Length:  2
New Length:  3
New Length:  4
New Length:  5
New Length:  6
New Length:  7
New Length:  8
New Length:  9
New Length:  10
Message: DD 10

Task k_003F5838 ran for 0 and 0.000000000 seconds
Task k_003F5838 is terminated due to UNHANDLED_EXCEPTION termination
Exception name: PROGRAM_ERROR
Message: attempt to tamper with cursors (vector is busy)


Task main_task_003F5008 ran for 0 and 0.109375000 seconds
Task main_task_003F5008 is terminated due to NORMAL termination
[2012-10-30 18:00:35] process terminated successfully (elapsed time: 20.60s)



^ permalink raw reply	[relevance 5%]

* Re: Tasking troubles, unexpected termination.
  @ 2012-10-30 23:01  5% ` Adam Beneschan
  2012-10-31  1:05  5%   ` Anh Vo
  0 siblings, 1 reply; 23+ results
From: Adam Beneschan @ 2012-10-30 23:01 UTC (permalink / raw)


On Tuesday, October 30, 2012 3:03:45 PM UTC-7, Shark8 wrote:

> Also, if there is some tasking-exceptions interaction, how do I force them to display [and/or handle them] instead of falling off a cliff?

Have you looked into Ada.Task_Termination?  (RM C.7.3)  That's just the first thought off the top of my head; I haven't looked at your code closely.

                           -- Adam




^ permalink raw reply	[relevance 5%]

* Re: Is Text_IO.Put_Line() thread-safe?
  @ 2012-06-14 14:35  5%   ` Adam Beneschan
  0 siblings, 0 replies; 23+ results
From: Adam Beneschan @ 2012-06-14 14:35 UTC (permalink / raw)


On Thursday, June 14, 2012 6:49:45 AM UTC-7, Robert A Duff wrote:

> It's a good idea to put an exception handler at the bottom of every
> task body, and do some debugging output there.  Otherwise, an
> exception will cause the task to silently vanish.  This is a
> language design flaw.

Starting with Ada 2005, you can also use Ada.Task_Termination.Set_Dependents_Fallback_Handler in your main program.  (See RM C.7.3.)  Probably you should do both.

                              -- Adam





^ permalink raw reply	[relevance 5%]

* Re: task abortion
  2012-01-26 16:47  5%     ` Anh Vo
@ 2012-01-31 13:25  0%       ` tonyg
  0 siblings, 0 replies; 23+ results
From: tonyg @ 2012-01-31 13:25 UTC (permalink / raw)


On Jan 26, 4:47 pm, Anh Vo <anhvofrc...@gmail.com> wrote:
> On Jan 26, 1:12 am, tonyg <tonytheg...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > On Jan 25, 10:43 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
>
> > > On Wed, 25 Jan 2012 02:11:55 -0800 (PST), tonyg wrote:
> > > > I want to be able to abort a task if it has not responded for a while,
> > > > and then start a new one in its stead.
>
> > > > I have a pointer going to the concerned task.
>
> > > > Each task has a 'stop accept' in its rendezvous which forces it out of
> > > > its loop so that it ends, but if the task has frozen for some reason
> > > > then I want to abort.
>
> > > What are you going to achieve by that?
>
> > > Consider the scenarios:
>
> > > 1. The task crashed, it is already terminated then.
>
> > > 2. The task is looping somewhere:
>
> > > 2.a. What about the resources it owns? Local resources are usually freed
> > > when the task is aborted. But if you have some globally allocated memory,
> > > semaphores etc, they all get lost unless freed by some local controlled
> > > objects, "holders" releasing the resources upon finalization, as they leave
> > > the scope upon task abort. Now:
>
> > > 2.b. What if the task is frozen in an abort-deferred thing? Finalization is
> > > such a thing. Abort-deferred stuff cannot be aborted. Note that system I/O
> > > is most likely non-abortable. I.e. you would not be able to abort
> > > Ada.Text_IO.Get_Line or recv on a socket etc anyway.
>
> > > All in one, aborting tasks doing complex stuff is not likely to work in a
> > > reasonable way. Aborting tasks doing simple stuff is not needed, such tasks
> > > impose no problems anyway. Ergo, it is not likely you would need to abort
> > > any task.
>
> > > If you decided for aborting, you would have to redesign almost everything
> > > and in an extremely careful way in order to make tasks logically abortable.
> > > That means to make continuation possible and meaningful after aborting some
> > > tasks. Now a guess: making the tasks right and thus preventing a need
> > > aborting them, would probably be far less efforts...
>
> > > --
> > > Regards,
> > > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de
>
> > Since I wrote my message I have discovered the package
> > Ada.Task_Identification. I totally agree with your argument on not
> > having them fail in the first place. My strategy should be then not to
> > abort :), I'm going to use that package just to monitor my tasks and
> > see if any freeze for some IO reason. Thanks for the advice.
>
> Just in case your task disappear which I do not expect it will, you
> can use package Ada.Task_Termination to query the reason (Normal,
> Abnormal, Unhandled_Exception) it dies.
>
> Anh Vo

Thabjs Anh for that



^ permalink raw reply	[relevance 0%]

* Re: task abortion
  @ 2012-01-26 16:47  5%     ` Anh Vo
  2012-01-31 13:25  0%       ` tonyg
  0 siblings, 1 reply; 23+ results
From: Anh Vo @ 2012-01-26 16:47 UTC (permalink / raw)


On Jan 26, 1:12 am, tonyg <tonytheg...@gmail.com> wrote:
> On Jan 25, 10:43 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>
>
>
>
>
>
>
>
> > On Wed, 25 Jan 2012 02:11:55 -0800 (PST), tonyg wrote:
> > > I want to be able to abort a task if it has not responded for a while,
> > > and then start a new one in its stead.
>
> > > I have a pointer going to the concerned task.
>
> > > Each task has a 'stop accept' in its rendezvous which forces it out of
> > > its loop so that it ends, but if the task has frozen for some reason
> > > then I want to abort.
>
> > What are you going to achieve by that?
>
> > Consider the scenarios:
>
> > 1. The task crashed, it is already terminated then.
>
> > 2. The task is looping somewhere:
>
> > 2.a. What about the resources it owns? Local resources are usually freed
> > when the task is aborted. But if you have some globally allocated memory,
> > semaphores etc, they all get lost unless freed by some local controlled
> > objects, "holders" releasing the resources upon finalization, as they leave
> > the scope upon task abort. Now:
>
> > 2.b. What if the task is frozen in an abort-deferred thing? Finalization is
> > such a thing. Abort-deferred stuff cannot be aborted. Note that system I/O
> > is most likely non-abortable. I.e. you would not be able to abort
> > Ada.Text_IO.Get_Line or recv on a socket etc anyway.
>
> > All in one, aborting tasks doing complex stuff is not likely to work in a
> > reasonable way. Aborting tasks doing simple stuff is not needed, such tasks
> > impose no problems anyway. Ergo, it is not likely you would need to abort
> > any task.
>
> > If you decided for aborting, you would have to redesign almost everything
> > and in an extremely careful way in order to make tasks logically abortable.
> > That means to make continuation possible and meaningful after aborting some
> > tasks. Now a guess: making the tasks right and thus preventing a need
> > aborting them, would probably be far less efforts...
>
> > --
> > Regards,
> > Dmitry A. Kazakovhttp://www.dmitry-kazakov.de
>
> Since I wrote my message I have discovered the package
> Ada.Task_Identification. I totally agree with your argument on not
> having them fail in the first place. My strategy should be then not to
> abort :), I'm going to use that package just to monitor my tasks and
> see if any freeze for some IO reason. Thanks for the advice.

Just in case your task disappear which I do not expect it will, you
can use package Ada.Task_Termination to query the reason (Normal,
Abnormal, Unhandled_Exception) it dies.

Anh Vo



^ permalink raw reply	[relevance 5%]

* Re: Class with task destructor
  2011-11-30  2:21  6%       ` Adam Beneschan
  2011-11-30  8:41  0%         ` Dmitry A. Kazakov
@ 2011-12-01  1:58  0%         ` Rego, P.
  1 sibling, 0 replies; 23+ results
From: Rego, P. @ 2011-12-01  1:58 UTC (permalink / raw)


> Ada.Task_Termination (see C.7.3) may be able to help.  You could
> define a protected object with a handler that sets a toggle and an
> entry that waits on the toggle, use Set_Specific_Handler to cause the
> handler to be executed when the task terminates, then call the
> protected entry to wait for the toggle.  (Maybe someone's already
> written a publicly available package that defines a
> Delay_Until_Task_Termination routine that could be used on
> T_Ptr.Primary'Identity, 
Ok. Great! Thanks.

> and with underscores in the name so it doesn't look like a *&#@^#$ Windows API routine...  :)
ok :)



^ permalink raw reply	[relevance 0%]

* Re: Class with task destructor
  2011-11-30  8:41  0%         ` Dmitry A. Kazakov
@ 2011-12-01  0:35  0%           ` Randy Brukardt
  0 siblings, 0 replies; 23+ results
From: Randy Brukardt @ 2011-12-01  0:35 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:ey516bovprzb$.1tjszfc528chj$.dlg@40tude.net...
> On Tue, 29 Nov 2011 18:21:51 -0800 (PST), Adam Beneschan wrote:
...
>> I don't know of a good way
>> around this (besides Ada.Task_Termination).
>
> I am using polling for T'Terminated after the rendezvous.

That's the Ada 83 solution, and there really isn't anything better in the 
language. Not sure if there even could be (I'm not a top-level expert on 
real-time issues, beyond what the Janus/Ada runtime does).

...
> Not a feature, rather a plain language design bug. Unchecked_Deallocation
> shall wait for the object's finalization. Finalization of a task evidently
> includes its termination. So Unchecked_Deallocation must block until
> termination before it frees anything.

The problem here is that finalization and task termination are different 
operations according to the language, and task termination generally has to 
be done first. This was done, I believe, so that any running task does not 
have to worry about having the objects it accesses finalized.

I usually agree that this is wrong, but actually it doesn't matter what 
choice is made -- any choice will be wrong a large part of the time. The 
current choice, for instance, makes it possible for finalize routines to 
access objects that have already been finalized (and allocate objects of 
access types that already have been finalized) - a finalize routine often 
needs to protect against this if it needs to access anything outside of the 
object being finalized.

We had a lot of trouble with this in Claw, particularly because we wanted to 
use a global finalizable object to tell the library tasks when to terminate. 
But that doesn't work in Ada, because tasks are awaited before any 
library-level finalization is done -- and thus the tasks never get their 
shutdown entries called. We eventually found a tricky way to use 
Ada.Task_Identification to determine when the main subprogram has exited, 
and used that to terminate the tasks. (And then we had to get all of the Ada 
95 compilers to implement it properly -- that took a couple of years and an 
ACATS test.)

Switching the order of task waiting and finalization would have worked in 
this case, but it wouldn't work in general as the library tasks would then 
be accessing global objects that have been finalized. Which seems worse than 
the original problem.

Point is that all of these things are interelated, and it isn't always 
possible to make all of them perfect. (Tucker Taft calls this "moving the 
bump under the carpet"; you can move it around to different locations, but 
you can't get rid of it without tearing out the carpet. That happens a lot 
more often in language design than most people think.)

                                           Randy.





^ permalink raw reply	[relevance 0%]

* Re: Class with task destructor
  2011-11-30  2:21  6%       ` Adam Beneschan
@ 2011-11-30  8:41  0%         ` Dmitry A. Kazakov
  2011-12-01  0:35  0%           ` Randy Brukardt
  2011-12-01  1:58  0%         ` Rego, P.
  1 sibling, 1 reply; 23+ results
From: Dmitry A. Kazakov @ 2011-11-30  8:41 UTC (permalink / raw)


On Tue, 29 Nov 2011 18:21:51 -0800 (PST), Adam Beneschan wrote:

> The problem with waiting on the Finish entry of the task, as you
> attempted to do in your next post, is that it may create a race
> condition.  After the rendezvous is completed, there still may be some
> delay between the time the task finishes the ACCEPT and the time it
> actually terminates, and that still makes it possible that the caller
> could try to free the task before it has actually terminated (which is
> a bounded error according to the RM).  I don't know of a good way
> around this (besides Ada.Task_Termination).

I am using polling for T'Terminated after the rendezvous.

However I have an impression that it should be safe to call
Unchecked_Deallocation in GNAT prematurely.

> Maybe there are some
> missing features in the language,

Not a feature, rather a plain language design bug. Unchecked_Deallocation
shall wait for the object's finalization. Finalization of a task evidently
includes its termination. So Unchecked_Deallocation must block until
termination before it frees anything.

> such as (for instance) a TERMINATE
> statement that can be used inside an ACCEPT statement that causes the
> task to terminate, completes the rendezvous, and guarantees that when
> the calling task is unblocked, the called task will be terminated.

As for missing features, rather than the Task_Termination hack, there
should be some way for the task to communicate to its master upon
completion, e.g. a rendezvous. A handler has a disadvantage of being a
protected procedure.

Furthermore, if the master does not accept such a notification from a
failed slave, the exceptional state should somehow propagate into the
master. I didn't think about the details, but the language design is unsafe
here.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Class with task destructor
  @ 2011-11-30  2:21  6%       ` Adam Beneschan
  2011-11-30  8:41  0%         ` Dmitry A. Kazakov
  2011-12-01  1:58  0%         ` Rego, P.
  0 siblings, 2 replies; 23+ results
From: Adam Beneschan @ 2011-11-30  2:21 UTC (permalink / raw)


On Nov 29, 5:11 pm, "Rego, P." <pvr...@gmail.com> wrote:
> > You ought to wait until the task has terminated before freeing it.
>
> How could I wait for the task termination?
> Could be something like
>
>    procedure Destruct (T : access Test_Class) is
>       T_Ptr : Test_Class_Ptr := Test_Class_Ptr (T);
>    begin
>       T.Primary.Finish;
>       DelayUntilTaskTermination (T_Ptr.Primary);
>       Free (T_Ptr);
>    end Destruct;
>
> ? But is there some package with something like it?

Ada.Task_Termination (see C.7.3) may be able to help.  You could
define a protected object with a handler that sets a toggle and an
entry that waits on the toggle, use Set_Specific_Handler to cause the
handler to be executed when the task terminates, then call the
protected entry to wait for the toggle.  (Maybe someone's already
written a publicly available package that defines a
Delay_Until_Task_Termination routine that could be used on
T_Ptr.Primary'Identity, and with underscores in the name so it doesn't
look like a *&#@^#$ Windows API routine...  :)  I haven't tried this,
by the way.

The problem with waiting on the Finish entry of the task, as you
attempted to do in your next post, is that it may create a race
condition.  After the rendezvous is completed, there still may be some
delay between the time the task finishes the ACCEPT and the time it
actually terminates, and that still makes it possible that the caller
could try to free the task before it has actually terminated (which is
a bounded error according to the RM).  I don't know of a good way
around this (besides Ada.Task_Termination).  Maybe there are some
missing features in the language, such as (for instance) a TERMINATE
statement that can be used inside an ACCEPT statement that causes the
task to terminate, completes the rendezvous, and guarantees that when
the calling task is unblocked, the called task will be terminated.

                           -- Adam



^ permalink raw reply	[relevance 6%]

* Re: Tail recursion upon task destruction
  2009-11-18 10:31  4%     ` stefan-lucks
  2009-11-18 17:48  5%       ` Dmitry A. Kazakov
@ 2009-11-19  9:25  0%       ` Egil Høvik
  1 sibling, 0 replies; 23+ results
From: Egil Høvik @ 2009-11-19  9:25 UTC (permalink / raw)


On Nov 18, 11:31 am, stefan-lu...@see-the.signature wrote:
> On Wed, 18 Nov 2009, Dmitry A. Kazakov wrote:
> > Now consider a case when the last screw is removed from the device. This
> > is an operation eventually serviced by the device driver. I.e. within
> > the device driver, you see, it was the last screw of the device and *if*
> > there is no other references to the device, it must fall apart. This is
> > a case where you wanted the device to commit suicide. There is nobody
> > else out there to do this. The device is dangling. This is not the only
> > use case, just one possible case.
>
> OK, so you have a task (a device) which notices that it is no longer
> useful. You would like such a task to do some cleanup and to commit
> "suicide". Unfortunately, it can't do the cleanup after the "suicide",
> because it is "dead" then. And it can't cleanup itself before being
> "dead" because it needs its local memory until the very moment of its
> "death".
>
> But couldn't you just use (or maybe abuse) the features from
> Ada.Task_Termination to do perform the cleanup, after the task has died?
> Even if it the "death" is not by suicide (apart from
> "suicide" = regular termination, the options are "murder" = abort and
> "accident" = unhandled exception).
> See <http://www.adaic.org/standards/05rat/html/Rat-5-2.html#I1150>.
>
> --
> ------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
>                Stefan dot Lucks at uni minus weimar dot de
> ------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------


This would still be a bounded error.
A task is not terminated until the task body has been finalized RM-9.3
(5),
and since Task_Termination handlers are executed as part of the
finalization
of task bodies RM-C.7.3(14/2), you would violate RM-13.11.2(11) by
deallocating
the task in the handler.

--
~egilhh




^ permalink raw reply	[relevance 0%]

* Re: Tail recursion upon task destruction
  2009-11-18 10:31  4%     ` stefan-lucks
@ 2009-11-18 17:48  5%       ` Dmitry A. Kazakov
  2009-11-19  9:25  0%       ` Egil Høvik
  1 sibling, 0 replies; 23+ results
From: Dmitry A. Kazakov @ 2009-11-18 17:48 UTC (permalink / raw)


On Wed, 18 Nov 2009 11:31:59 +0100, stefan-lucks@see-the.signature wrote:

> On Wed, 18 Nov 2009, Dmitry A. Kazakov wrote:
> 
>> Now consider a case when the last screw is removed from the device. This 
>> is an operation eventually serviced by the device driver. I.e. within 
>> the device driver, you see, it was the last screw of the device and *if* 
>> there is no other references to the device, it must fall apart. This is 
>> a case where you wanted the device to commit suicide. There is nobody 
>> else out there to do this. The device is dangling. This is not the only 
>> use case, just one possible case.
> 
> OK, so you have a task (a device) which notices that it is no longer 
> useful. You would like such a task to do some cleanup and to commit 
> "suicide". Unfortunately, it can't do the cleanup after the "suicide", 
> because it is "dead" then. And it can't cleanup itself before being 
> "dead" because it needs its local memory until the very moment of its 
> "death".
> 
> But couldn't you just use (or maybe abuse) the features from 
> Ada.Task_Termination to do perform the cleanup, after the task has died?
> Even if it the "death" is not by suicide (apart from 
> "suicide" = regular termination, the options are "murder" = abort and
> "accident" = unhandled exception). 
> See <http://www.adaic.org/standards/05rat/html/Rat-5-2.html#I1150>.

Yes, it is an interesting option. One could terminate the task and from the
handler kill the object. The difficulty is that Ada.Task_Termination is not
generic. It is not possible to pass a reference to the object to the
handler.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 5%]

* Re: Tail recursion upon task destruction
  @ 2009-11-18 10:31  4%     ` stefan-lucks
  2009-11-18 17:48  5%       ` Dmitry A. Kazakov
  2009-11-19  9:25  0%       ` Egil Høvik
  0 siblings, 2 replies; 23+ results
From: stefan-lucks @ 2009-11-18 10:31 UTC (permalink / raw)


On Wed, 18 Nov 2009, Dmitry A. Kazakov wrote:

> Now consider a case when the last screw is removed from the device. This 
> is an operation eventually serviced by the device driver. I.e. within 
> the device driver, you see, it was the last screw of the device and *if* 
> there is no other references to the device, it must fall apart. This is 
> a case where you wanted the device to commit suicide. There is nobody 
> else out there to do this. The device is dangling. This is not the only 
> use case, just one possible case.

OK, so you have a task (a device) which notices that it is no longer 
useful. You would like such a task to do some cleanup and to commit 
"suicide". Unfortunately, it can't do the cleanup after the "suicide", 
because it is "dead" then. And it can't cleanup itself before being 
"dead" because it needs its local memory until the very moment of its 
"death".

But couldn't you just use (or maybe abuse) the features from 
Ada.Task_Termination to do perform the cleanup, after the task has died?
Even if it the "death" is not by suicide (apart from 
"suicide" = regular termination, the options are "murder" = abort and
"accident" = unhandled exception). 
See <http://www.adaic.org/standards/05rat/html/Rat-5-2.html#I1150>. 



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[relevance 4%]

* Re: task model
  @ 2009-10-16 14:57  5%         ` Brad Moore
  0 siblings, 0 replies; 23+ results
From: Brad Moore @ 2009-10-16 14:57 UTC (permalink / raw)


Georg Bauhaus wrote:
> 4.  add an exception handler to your tasks.
> Have it print a message, for example, and
> then re-raise the exception.  Otherwise tasks
> may fail in silence and you never learn what
> has happened.

Or use the Ada 2005 package, Ada.Task_Termination
which allows you to install a handler that
gets called when tasks terminate.



^ permalink raw reply	[relevance 5%]

* Re: [Ravenscar] run tasks on events
  2008-05-30 15:24  5%         ` Alex R. Mosteo
@ 2008-05-30 15:35  5%           ` Ed Falis
  0 siblings, 0 replies; 23+ results
From: Ed Falis @ 2008-05-30 15:35 UTC (permalink / raw)


On Fri, 30 May 2008 11:24:22 -0400, Alex R. Mosteo  
<devnull@mailinator.com> wrote:

> Look also at Ada.Task_Termination, although I don't know if it mix with
> ravenscar.

I may be mistaken, but I beleive the Ravenscar profile prohibits any units  
depending on Ada.Task_Termination.

I would also recommend Burns and Wellings "Concurrent and Real Time  
Programming in Ada".  It is extremely comprehensive.



^ permalink raw reply	[relevance 5%]

* Re: [Ravenscar] run tasks on events
  @ 2008-05-30 15:24  5%         ` Alex R. Mosteo
  2008-05-30 15:35  5%           ` Ed Falis
  0 siblings, 1 reply; 23+ results
From: Alex R. Mosteo @ 2008-05-30 15:24 UTC (permalink / raw)


Sebastian Hanigk wrote:

> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> 
> Hello!
> 
>> Since the Ravenscar profile contains the restriction
>> No_Task_Termination, by LRM D.7.15(1/2) it is implementation defined
>> what happens when a Ravenscar task terminates due to an unhandled
>> exception or for other reasons. It may be reported or signalled in
>> some way, or not.
> 
> I'm using GNAT 4.0.2 on Solaris 10 (AMD); it seems that my second test
> task has silently died.

Look also at Ada.Task_Termination, although I don't know if it mix with
ravenscar.



^ permalink raw reply	[relevance 5%]

* Re: [Ravenscar] run tasks on events
    @ 2008-05-30 11:59  6%       ` stefan-lucks
  1 sibling, 0 replies; 23+ results
From: stefan-lucks @ 2008-05-30 11:59 UTC (permalink / raw)


On Fri, 30 May 2008, Niklas Holsti wrote:

> In unrestricted Ada, if an exception occurs in a task, and the task does not
> handle the exception, the task by default terminates silently when the
> exception propagates out of the task. If you want to know about exceptions in
> a task, you should put a last-chance, catch-all exception handler in the task
> body ("exception when others => ...").

You don't need this in Ada 05 any more. You can define some callback 
procedures, to do something in the case of unhandled exceptions (and 
normal and abnormal termination as well, if you want to). 


The following is similar to an example in Barnes' book, except that the 
usage avoids race conditions:

--------------------------------------------------------------------------

Package defined in 
<http://www.adaic.org/standards/05rm/html/RM-C-7-3.html>:

with Ada.Task_Identification; with Ada.Exceptions;

package Ada.Task_Termination is
  ...
  type Cause_Of_Termination is (Normal, Abnormal, Unhandled_Exception);
  type Termination_Handler is access protected procedure
    (Cause : in Cause_Of_Termination;
     T     : in Ada.Task_Identification.Task_Id;
     X     : in Ada.Exceptions.Exception_Occurrence);

  procedure Set_Dependents_Fallback_Handler(Handler: in Termination_Handler);
  ...
end Ada.Task_Termination;

--------------------------------------------------------------------------

Specification of Callback:

protected End_Of is
  
  procedure World(C: Cause_Of_Termination;
                  T: Task_ID;
                  X: Exception_Occurrence);

end End_Of;

--------------------------------------------------------------------------

Implementation of Callback:

  procedure World(C: Cause_Of_Termination;
                  T: Task_ID;
                  X: Exception_Occurrence);

  begin
    case C is
      when Normal => 
        null;
      when Abnormal => 
        Put_Log("abnormal termination of Task" & Image(T));
      when Unhandled_Exception =>
        Put_Log("unhandled exception in Task" & Image(T));
        Put_Log(Exception_Information(X));
    end case;
  end World;

--------------------------------------------------------------------------

Usage of callback (typically in main program / environment task):

begin 
  Set_Dependents_Fallback_Handler(End_Of.World);
  declare -- any task you want
    A_Bunch_Of_Tasks: array (0 .. 1023) of Some_Task_Type;
    Alice, Bob: Some_Other_Task_Type;
  begin
    ...
    -- Whenever any of our tasks terminates normally or abnormally or 
    -- propagates an exception, End_Of.World is called. 
  end;
end;




So long

Stefan

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[relevance 6%]

* Re: contracted exceptions
  2007-06-09  0:19  0%           ` Randy Brukardt
@ 2007-06-09 18:04  4%             ` Robert A Duff
  0 siblings, 0 replies; 23+ results
From: Robert A Duff @ 2007-06-09 18:04 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Pascal Obry" <pascal@obry.net> wrote in message
> news:4669BBBB.8040806@obry.net...
>> Stefan Lucks a �crit :
>> > If a task fails to handle an exception raised somewhere inside, the task
>> > silently dies -- without notifying anyone. Enforcing the subprograms
>> > used by the task to precisely specify "this subprogram might raise these
>> > exceptions and none else" would help a lot ...
>>
>> That's really different. And think about it, since a task is mapped to a
>> thread which comes with its own stack... who could possibly handle this
>> exception ?
>
> And more importantly, where would it be raised? If it was raised in the
> parent task, that could happen anywhere, which would be a design nightmare
> (a different nightmare than the current one, anyway).

I can think of lots of rules that are not perfect, but are at least
superior to the existing rule of silently ignoring the exception.

The simplest would be to terminate the entire program immediately.
And print an error message on systems where that makes sense.
Ada has no way to terminate the whole program (i.e. call "exit"),
but it should.

Or just print an error message.

Or raise Program_Error in the parent task at the point where that task
awaits its dependents.  Option: abort all the siblings as well.

Or put the task to sleep, so the parent waits forever (and the
programmer has to debug a "deadlock").

>> And note that in Ada 2005 you can use Ada.Task_Termination to register
>> termination notifications.
>
> It's unfortunate that the default isn't to notify someone, however.

Right.  Ada.Task_Termination is another way, and the default should be
to raise alarms of some sort.

>...Worse,
> this interface might not work in out-of-memory circumstances (one of the
> most common reasons for task failure, at least in Janus/Ada programs where
> the default stack size is rather small).

Right, out-of-memory is a difficult issue.  I don't know of any language
that solves it well.  You might think you could do:

    task body T is
    begin
        declare
            ...
        begin
            ...
        exception
            when others =>
                ...
        end;
    end T;

and carefully prove that the handler code cannot raise any exceptions
itself.  But you can't prove the absense of Storage_Error in Ada.

My solution: allow the programmer to declare that certain regions of
code cannot run out of memory.  The compiler must reserve enough memory
(and if can't, then raise S_E before entering that region).  Of course,
what you can do in such a region is implementation dependent.

This would make life difficult for compilers that generate C,
or any other target language that doesn't have sufficient control
over memory use.  :-(

- Bob



^ permalink raw reply	[relevance 4%]

* Re: contracted exceptions
  2007-06-08 20:27  5%         ` Pascal Obry
@ 2007-06-09  0:19  0%           ` Randy Brukardt
  2007-06-09 18:04  4%             ` Robert A Duff
  0 siblings, 1 reply; 23+ results
From: Randy Brukardt @ 2007-06-09  0:19 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1157 bytes --]

"Pascal Obry" <pascal@obry.net> wrote in message
news:4669BBBB.8040806@obry.net...
> Stefan Lucks a �crit :
> > If a task fails to handle an exception raised somewhere inside, the task
> > silently dies -- without notifying anyone. Enforcing the subprograms
> > used by the task to precisely specify "this subprogram might raise these
> > exceptions and none else" would help a lot ...
>
> That's really different. And think about it, since a task is mapped to a
> thread which comes with its own stack... who could possibly handle this
> exception ?

And more importantly, where would it be raised? If it was raised in the
parent task, that could happen anywhere, which would be a design nightmare
(a different nightmare than the current one, anyway).

> And note that in Ada 2005 you can use Ada.Task_Termination to register
> termination notifications.

It's unfortunate that the default isn't to notify someone, however. Worse,
this interface might not work in out-of-memory circumstances (one of the
most common reasons for task failure, at least in Janus/Ada programs where
the default stack size is rather small).

                      Randy.





^ permalink raw reply	[relevance 0%]

* Re: contracted exceptions
  @ 2007-06-08 20:27  5%         ` Pascal Obry
  2007-06-09  0:19  0%           ` Randy Brukardt
  0 siblings, 1 reply; 23+ results
From: Pascal Obry @ 2007-06-08 20:27 UTC (permalink / raw)
  To: Stefan Lucks

Stefan Lucks a �crit :
> If a task fails to handle an exception raised somewhere inside, the task
> silently dies -- without notifying anyone. Enforcing the subprograms
> used by the task to precisely specify "this subprogram might raise these
> exceptions and none else" would help a lot ...

That's really different. And think about it, since a task is mapped to a
thread which comes with its own stack... who could possibly handle this
exception ?

And note that in Ada 2005 you can use Ada.Task_Termination to register
termination notifications.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[relevance 5%]

Results 1-23 of 23 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2007-06-06 21:33     Reconsidering assignment Maciej Sobczak
2007-06-07  9:27     ` Dmitry A. Kazakov
2007-06-07 16:54       ` contracted exceptions (was Re: Reconsidering assignment) Ray Blaak
2007-06-08 12:10         ` contracted exceptions Robert A Duff
2007-06-08 15:56           ` Stefan Lucks
2007-06-08 20:27  5%         ` Pascal Obry
2007-06-09  0:19  0%           ` Randy Brukardt
2007-06-09 18:04  4%             ` Robert A Duff
2008-05-28 19:14     [Ravenscar] run tasks on events Sebastian Hanigk
2008-05-30  7:26     ` Niklas Holsti
2008-05-30  8:57       ` Sebastian Hanigk
2008-05-30 10:47         ` Niklas Holsti
2008-05-30 11:17           ` Sebastian Hanigk
2008-05-30 15:24  5%         ` Alex R. Mosteo
2008-05-30 15:35  5%           ` Ed Falis
2008-05-30 11:59  6%       ` stefan-lucks
2009-10-15 17:43     task model Mike
2009-10-15 18:00     ` Ludovic Brenta
2009-10-15 19:15       ` Anh Vo
2009-10-15 19:54         ` Dmitry A. Kazakov
2009-10-16 14:06           ` Georg Bauhaus
2009-10-16 14:57  5%         ` Brad Moore
2009-11-17 10:17     Tail recursion upon task destruction Dmitry A. Kazakov
2009-11-17 21:38     ` Randy Brukardt
2009-11-18  8:41       ` Dmitry A. Kazakov
2009-11-18 10:31  4%     ` stefan-lucks
2009-11-18 17:48  5%       ` Dmitry A. Kazakov
2009-11-19  9:25  0%       ` Egil Høvik
2011-11-23  1:50     Class with task destructor Rego, P.
2011-11-23  8:35     ` Dmitry A. Kazakov
2011-11-23  9:05       ` Simon Wright
2011-11-30  1:11         ` Rego, P.
2011-11-30  2:21  6%       ` Adam Beneschan
2011-11-30  8:41  0%         ` Dmitry A. Kazakov
2011-12-01  0:35  0%           ` Randy Brukardt
2011-12-01  1:58  0%         ` Rego, P.
2012-01-25 10:11     task abortion tonyg
2012-01-25 10:43     ` Dmitry A. Kazakov
2012-01-26  9:12       ` tonyg
2012-01-26 16:47  5%     ` Anh Vo
2012-01-31 13:25  0%       ` tonyg
2012-06-14 12:53     Is Text_IO.Put_Line() thread-safe? awdorrin
2012-06-14 13:49     ` Robert A Duff
2012-06-14 14:35  5%   ` Adam Beneschan
2012-10-30 22:03     Tasking troubles, unexpected termination Shark8
2012-10-30 23:01  5% ` Adam Beneschan
2012-10-31  1:05  5%   ` Anh Vo
2012-10-31  2:17  6%     ` Shark8
2016-04-21 10:23  7% timer_server triggers Task_Termination handler Per Dalgas Jakobsen
2020-01-30  8:55     Last chance handler on a PC ahlan
2020-01-30 19:35     ` ahlan
2020-01-30 20:02  5%   ` Jeffrey R. Carter
2020-01-30 20:26  0%     ` Niklas Holsti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox