===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1992-2013, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -1075,7 +1075,7 @@
procedure Search_Fall_Back_Handler (ID : Task_Id);
-- Procedure that searches recursively a fall-back handler through the
-- master relationship. If the handler is found, its pointer is stored
- -- in TH.
+ -- in TH. It stops when the handler is found or when the ID is null.
------------------------------
-- Search_Fall_Back_Handler --
@@ -1083,21 +1083,22 @@
procedure Search_Fall_Back_Handler (ID : Task_Id) is
begin
+ -- A null Task_Id indicates that we have reached the root of the
+ -- task hierarchy and no handler has been found.
+
+ if ID = null then
+ return;
+
-- If there is a fall back handler, store its pointer for later
-- execution.
- if ID.Common.Fall_Back_Handler /= null then
+ elsif ID.Common.Fall_Back_Handler /= null then
TH := ID.Common.Fall_Back_Handler;
-- Otherwise look for a fall back handler in the parent
- elsif ID.Common.Parent /= null then
+ else
Search_Fall_Back_Handler (ID.Common.Parent);
-
- -- Otherwise, do nothing
-
- else
- return;
end if;
end Search_Fall_Back_Handler;
@@ -1331,9 +1332,12 @@
TH := Self_ID.Common.Specific_Handler;
else
-- Look for a fall-back handler following the master relationship
- -- for the task.
+ -- for the task. As specified in ARM C.7.3 par. 9/2, "the fall-back
+ -- handler applies only to the dependent tasks of the task". Hence,
+ -- if the terminating tasks (Self_ID) had a fall-back handler, it
+ -- would not apply to itself, so we start the search with the parent.
- Search_Fall_Back_Handler (Self_ID);
+ Search_Fall_Back_Handler (Self_ID.Common.Parent);
end if;
Unlock (Self_ID);
===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1999-2013, Free Software Foundation, Inc. --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -268,49 +268,45 @@
Save_Occurrence (EO, E);
end;
- -- Look for a fall-back handler. It can be either in the task itself
- -- or in the environment task. Note that this code is always executed
- -- by a task whose master is the environment task. The task termination
- -- code for the environment task is executed by
- -- SSL.Task_Termination_Handler.
+ -- Look for a fall-back handler.
-- This package is part of the restricted run time which supports
-- neither task hierarchies (No_Task_Hierarchy) nor specific task
-- termination handlers (No_Specific_Termination_Handlers).
- -- There is no need for explicit protection against race conditions
- -- for Self_ID.Common.Fall_Back_Handler because this procedure can
- -- only be executed by Self, and the Fall_Back_Handler can only be
- -- modified by Self.
+ -- As specified in ARM C.7.3 par. 9/2, "the fall-back handler applies
+ -- only to the dependent tasks of the task". Hence, if the terminating
+ -- tasks (Self_ID) had a fall-back handler, it would not apply to
+ -- itself. This code is always executed by a task whose master is the
+ -- environment task (the task termination code for the environment task
+ -- is executed by SSL.Task_Termination_Handler), so the fall-back
+ -- handler to execute for this task can only be defined by its parent
+ -- (there is no grandparent).
- if Self_ID.Common.Fall_Back_Handler /= null then
- Self_ID.Common.Fall_Back_Handler (Cause, Self_ID, EO);
- else
- declare
- TH : Termination_Handler := null;
+ declare
+ TH : Termination_Handler := null;
- begin
- if Single_Lock then
- Lock_RTS;
- end if;
+ begin
+ if Single_Lock then
+ Lock_RTS;
+ end if;
- Write_Lock (Self_ID.Common.Parent);
+ Write_Lock (Self_ID.Common.Parent);
- TH := Self_ID.Common.Parent.Common.Fall_Back_Handler;
+ TH := Self_ID.Common.Parent.Common.Fall_Back_Handler;
- Unlock (Self_ID.Common.Parent);
+ Unlock (Self_ID.Common.Parent);
- if Single_Lock then
- Unlock_RTS;
- end if;
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
- -- Execute the task termination handler if we found it
+ -- Execute the task termination handler if we found it
- if TH /= null then
- TH.all (Cause, Self_ID, EO);
- end if;
- end;
- end if;
+ if TH /= null then
+ TH.all (Cause, Self_ID, EO);
+ end if;
+ end;
Terminate_Task (Self_ID);
end Task_Wrapper;
===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 2004-2013, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -181,12 +181,13 @@
-- There is no need for explicit protection against race conditions for
-- this part because it can only be executed by the environment task
- -- after all the other tasks have been finalized.
+ -- after all the other tasks have been finalized. Note that there is no
+ -- fall-back handler which could apply to this environment task because
+ -- it has no parents, and, as specified in ARM C.7.3 par. 9/2, "the
+ -- fall-back handler applies only to the dependent tasks of the task".
if Self_Id.Common.Specific_Handler /= null then
Self_Id.Common.Specific_Handler.all (Cause, Self_Id, EO);
- elsif Self_Id.Common.Fall_Back_Handler /= null then
- Self_Id.Common.Fall_Back_Handler.all (Cause, Self_Id, EO);
end if;
end Task_Termination_Handler_T;