mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-24 12:31:25 +08:00
s-tasini.ads, [...] (Undefer_Abortion): Handle case of Self_Id.Deferral_Level = 0.
* 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
This commit is contained in:
parent
b558cbe01b
commit
e9906cbf17
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user