File : a-taster.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT RUN-TIME COMPONENTS                         --
   4 --                                                                          --
   5 --                 A D A . T A S K _ T E R M I N A T I O N                  --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2005-2009, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with System.Tasking;
  33 with System.Task_Primitives.Operations;
  34 with System.Parameters;
  35 with System.Soft_Links;
  36 
  37 with Ada.Unchecked_Conversion;
  38 
  39 package body Ada.Task_Termination is
  40 
  41    use type Ada.Task_Identification.Task_Id;
  42 
  43    package STPO renames System.Task_Primitives.Operations;
  44    package SSL  renames System.Soft_Links;
  45 
  46    use System.Parameters;
  47 
  48    -----------------------
  49    -- Local subprograms --
  50    -----------------------
  51 
  52    function To_TT is new Ada.Unchecked_Conversion
  53      (System.Tasking.Termination_Handler, Termination_Handler);
  54 
  55    function To_ST is new Ada.Unchecked_Conversion
  56      (Termination_Handler, System.Tasking.Termination_Handler);
  57 
  58    function To_Task_Id is new Ada.Unchecked_Conversion
  59      (Ada.Task_Identification.Task_Id, System.Tasking.Task_Id);
  60 
  61    -----------------------------------
  62    -- Current_Task_Fallback_Handler --
  63    -----------------------------------
  64 
  65    function Current_Task_Fallback_Handler return Termination_Handler is
  66    begin
  67       --  There is no need for explicit protection against race conditions
  68       --  for this function because this function can only be executed by
  69       --  Self, and the Fall_Back_Handler can only be modified by Self.
  70 
  71       return To_TT (STPO.Self.Common.Fall_Back_Handler);
  72    end Current_Task_Fallback_Handler;
  73 
  74    -------------------------------------
  75    -- Set_Dependents_Fallback_Handler --
  76    -------------------------------------
  77 
  78    procedure Set_Dependents_Fallback_Handler
  79      (Handler : Termination_Handler)
  80    is
  81       Self : constant System.Tasking.Task_Id := STPO.Self;
  82 
  83    begin
  84       SSL.Abort_Defer.all;
  85 
  86       if Single_Lock then
  87          STPO.Lock_RTS;
  88       end if;
  89 
  90       STPO.Write_Lock (Self);
  91 
  92       Self.Common.Fall_Back_Handler := To_ST (Handler);
  93 
  94       STPO.Unlock (Self);
  95 
  96       if Single_Lock then
  97          STPO.Unlock_RTS;
  98       end if;
  99 
 100       SSL.Abort_Undefer.all;
 101    end Set_Dependents_Fallback_Handler;
 102 
 103    --------------------------
 104    -- Set_Specific_Handler --
 105    --------------------------
 106 
 107    procedure Set_Specific_Handler
 108      (T       : Ada.Task_Identification.Task_Id;
 109       Handler : Termination_Handler)
 110    is
 111    begin
 112       --  Tasking_Error is raised if the task identified by T has already
 113       --  terminated. Program_Error is raised if the value of T is
 114       --  Null_Task_Id.
 115 
 116       if T = Ada.Task_Identification.Null_Task_Id then
 117          raise Program_Error;
 118       elsif Ada.Task_Identification.Is_Terminated (T) then
 119          raise Tasking_Error;
 120       else
 121          declare
 122             Target : constant System.Tasking.Task_Id := To_Task_Id (T);
 123 
 124          begin
 125             SSL.Abort_Defer.all;
 126 
 127             if Single_Lock then
 128                STPO.Lock_RTS;
 129             end if;
 130 
 131             STPO.Write_Lock (Target);
 132 
 133             Target.Common.Specific_Handler := To_ST (Handler);
 134 
 135             STPO.Unlock (Target);
 136 
 137             if Single_Lock then
 138                STPO.Unlock_RTS;
 139             end if;
 140 
 141             SSL.Abort_Undefer.all;
 142          end;
 143       end if;
 144    end Set_Specific_Handler;
 145 
 146    ----------------------
 147    -- Specific_Handler --
 148    ----------------------
 149 
 150    function Specific_Handler
 151      (T : Ada.Task_Identification.Task_Id) return Termination_Handler
 152    is
 153    begin
 154       --  Tasking_Error is raised if the task identified by T has already
 155       --  terminated. Program_Error is raised if the value of T is
 156       --  Null_Task_Id.
 157 
 158       if T = Ada.Task_Identification.Null_Task_Id then
 159          raise Program_Error;
 160       elsif Ada.Task_Identification.Is_Terminated (T) then
 161          raise Tasking_Error;
 162       else
 163          declare
 164             Target : constant System.Tasking.Task_Id := To_Task_Id (T);
 165             TH     : Termination_Handler;
 166 
 167          begin
 168             SSL.Abort_Defer.all;
 169 
 170             if Single_Lock then
 171                STPO.Lock_RTS;
 172             end if;
 173 
 174             STPO.Write_Lock (Target);
 175 
 176             TH := To_TT (Target.Common.Specific_Handler);
 177 
 178             STPO.Unlock (Target);
 179 
 180             if Single_Lock then
 181                STPO.Unlock_RTS;
 182             end if;
 183 
 184             SSL.Abort_Undefer.all;
 185 
 186             return TH;
 187          end;
 188       end if;
 189    end Specific_Handler;
 190 
 191 end Ada.Task_Termination;