-- 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 --
----------------------------
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
-- ?????
-- 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.
-- used for Defer_Abort
-- Undefer_Abort
-- Poll_Base_Priority_Change
+-- Do_Pending_Action
with System.Tasking.Queuing;
-- used for Enqueue
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
with System.Storage_Elements;
-- used for Storage_Array
+with System.Restrictions;
+-- used for Abort_Allowed
+
with System.Standard_Library;
-- used for Exception_Trace
(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;