]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s-tasini.ads, [...] (Undefer_Abortion): Handle case of Self_Id.Deferral_Level = 0.
authorArnaud Charlet <charlet@gcc.gnu.org>
Mon, 3 Jan 2005 15:42:23 +0000 (16:42 +0100)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 3 Jan 2005 15:42:23 +0000 (16:42 +0100)
* s-tasini.ads, s-tasini.adb (Undefer_Abortion): Handle case of
Self_Id.Deferral_Level = 0.
(Do_Pending_Action): Move this function to the spec.

* s-tasren.adb (Selective_Wait [Terminate_Selected]): Call
Do_Pending_Action explicitely when needed, in case we're using
No_Abort restrictions.

* s-tassta.adb (Create_Task): If Abort is not allowed, reset the
deferral level since it will not get changed by the generated code.
Keeping a default value of 1 would prevent some operations (e.g.
select or delay) to proceed successfully.

From-SVN: r92851

gcc/ada/s-tasini.adb
gcc/ada/s-tasini.ads
gcc/ada/s-tasren.adb
gcc/ada/s-tassta.adb

index 871b2d035d57b1cceea425c3dd94e7f2662e7482..c2bee15dc0f8c9243972d73dba1950128c24bd85 100644 (file)
@@ -128,10 +128,6 @@ package body System.Tasking.Initialization is
    --  Local Subprograms --
    ------------------------
 
-   procedure Do_Pending_Action (Self_ID : Task_Id);
-   --  This is introduced to allow more efficient
-   --  in-line expansion of Undefer_Abort.
-
    ----------------------------
    -- Tasking Initialization --
    ----------------------------
@@ -777,8 +773,24 @@ package body System.Tasking.Initialization is
       end if;
 
       Self_ID := STPO.Self;
-      pragma Assert (Self_ID.Deferral_Level > 0);
 
+      if Self_ID.Deferral_Level = 0 then
+
+         --  In case there are different views on whether Abort is supported
+         --  between the expander and the run time, we may end up with
+         --  Self_ID.Deferral_Level being equal to zero, when called from
+         --  the procedure created by the expander that corresponds to a
+         --  task body.
+
+         --  In this case, there's nothing to be done
+
+         --  See related code in System.Tasking.Stages.Create_Task resetting
+         --  Deferral_Level when System.Restrictions.Abort_Allowed is False.
+
+         return;
+      end if;
+
+      pragma Assert (Self_ID.Deferral_Level > 0);
       Self_ID.Deferral_Level := Self_ID.Deferral_Level - 1;
 
       if Self_ID.Deferral_Level = 0 then
index ca58df61e59ee9ed61cafd357664c42677950082..62bfc0c3463b7fdbed741ff44cff44ae13a7f809 100644 (file)
@@ -131,6 +131,14 @@ package System.Tasking.Initialization is
    --  ?????
    --  Try to phase out all uses of the above versions.
 
+   procedure Do_Pending_Action (Self_ID : Task_Id);
+   --  Only call with no locks, and when Self_ID.Pending_Action = True
+   --  Perform necessary pending actions (e.g. abortion, priority change).
+   --  This procedure is usually called when needed as a result of
+   --  calling Undefer_Abort, although in the case of e.g. No_Abort
+   --  restriction, it can be necessary to force execution of pending
+   --  actions.
+
    function Check_Abort_Status return Integer;
    --  Returns Boolean'Pos (True) iff abort signal should raise
    --  Standard.Abort_Signal. Only used by IRIX currently.
index 5763272ce247f05f6a196b30c0157d6edf74aae9..9002eeeb03134da64c29fa56bdcf0a702d166e2f 100644 (file)
@@ -55,6 +55,7 @@ with System.Tasking.Initialization;
 --  used for Defer_Abort
 --           Undefer_Abort
 --           Poll_Base_Priority_Change
+--           Do_Pending_Action
 
 with System.Tasking.Queuing;
 --  used for Enqueue
@@ -972,8 +973,20 @@ package body System.Tasking.Rendezvous is
                pragma Assert (Self_Id.Pending_ATC_Level = 0);
                pragma Assert (Self_Id.Awake_Count = 0);
 
-               --  Trust that it is OK to fall through.
-               null;
+               STPO.Unlock (Self_Id);
+
+               if Single_Lock then
+                  Unlock_RTS;
+               end if;
+
+               Index := Self_Id.Chosen_Index;
+               Initialization.Undefer_Abort_Nestable (Self_Id);
+
+               if Self_Id.Pending_Action then
+                  Initialization.Do_Pending_Action (Self_Id);
+               end if;
+
+               return;
 
             else
                --  Self_Id.Common.Call and Self_Id.Chosen_Index
index 784dade88d81c5d4ff8c00c0a425d0eefa3f2a66..e09b6a56459f38d6ac2df829f4943f80768d8e06 100644 (file)
@@ -103,6 +103,9 @@ with System.Secondary_Stack;
 with System.Storage_Elements;
 --  used for Storage_Array
 
+with System.Restrictions;
+--  used for Abort_Allowed
+
 with System.Standard_Library;
 --  used for Exception_Trace
 
@@ -614,6 +617,16 @@ package body System.Tasking.Stages is
            (Storage_Error'Identity, "Failed to initialize task");
       end if;
 
+      if not System.Restrictions.Abort_Allowed then
+
+         --  If Abort is not allowed, reset the deferral level since it will
+         --  not get changed by the generated code. Keeping a default value
+         --  of one would prevent some operations (e.g. select or delay) to
+         --  proceed successfully.
+
+         T.Deferral_Level := 0;
+      end if;
+
       T.Master_of_Task := Master;
       T.Master_Within := T.Master_of_Task + 1;