OSDN Git Service

PR c++/27714
[pf3gnuchains/gcc-fork.git] / gcc / ada / 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-2006, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the  contents of the part following the private keyword. --
14 --                                                                          --
15 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
16 -- terms of the  GNU General Public License as published  by the Free Soft- --
17 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
18 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
21 -- for  more details.  You should have  received  a copy of the GNU General --
22 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
23 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
24 -- Boston, MA 02110-1301, USA.                                              --
25 --                                                                          --
26 -- As a special exception,  if other files  instantiate  generics from this --
27 -- unit, or you link  this unit with other files  to produce an executable, --
28 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
29 -- covered  by the  GNU  General  Public  License.  This exception does not --
30 -- however invalidate  any other reasons why  the executable file  might be --
31 -- covered by the  GNU Public License.                                      --
32 --                                                                          --
33 -- GNAT was originally developed  by the GNAT team at  New York University. --
34 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
35 --                                                                          --
36 ------------------------------------------------------------------------------
37
38 with System.Tasking;
39 --  used for Task_Id
40
41 with System.Task_Primitives.Operations;
42 --  used for Self
43 --           Write_Lock
44 --           Unlock
45 --           Lock_RTS
46 --           Unlock_RTS
47
48 with System.Parameters;
49 --  used for Single_Lock
50
51 with System.Soft_Links;
52 --  use for Abort_Defer
53 --          Abort_Undefer
54
55 with Unchecked_Conversion;
56
57 package body Ada.Task_Termination is
58
59    use type Ada.Task_Identification.Task_Id;
60
61    package STPO renames System.Task_Primitives.Operations;
62    package SSL  renames System.Soft_Links;
63
64    use System.Parameters;
65
66    -----------------------
67    -- Local subprograms --
68    -----------------------
69
70    function To_TT is new Unchecked_Conversion
71      (System.Tasking.Termination_Handler, Termination_Handler);
72
73    function To_ST is new Unchecked_Conversion
74      (Termination_Handler, System.Tasking.Termination_Handler);
75
76    function To_Task_Id is new Unchecked_Conversion
77      (Ada.Task_Identification.Task_Id, System.Tasking.Task_Id);
78
79    -----------------------------------
80    -- Current_Task_Fallback_Handler --
81    -----------------------------------
82
83    function Current_Task_Fallback_Handler return Termination_Handler is
84    begin
85       --  There is no need for explicit protection against race conditions
86       --  for this function because this function can only be executed by
87       --  Self, and the Fall_Back_Handler can only be modified by Self.
88
89       return To_TT (STPO.Self.Common.Fall_Back_Handler);
90    end Current_Task_Fallback_Handler;
91
92    -------------------------------------
93    -- Set_Dependents_Fallback_Handler --
94    -------------------------------------
95
96    procedure Set_Dependents_Fallback_Handler
97      (Handler : Termination_Handler)
98    is
99       Self : constant System.Tasking.Task_Id := STPO.Self;
100
101    begin
102       SSL.Abort_Defer.all;
103
104       if Single_Lock then
105          STPO.Lock_RTS;
106       end if;
107
108       STPO.Write_Lock (Self);
109
110       Self.Common.Fall_Back_Handler := To_ST (Handler);
111
112       STPO.Unlock (Self);
113
114       if Single_Lock then
115          STPO.Unlock_RTS;
116       end if;
117
118       SSL.Abort_Undefer.all;
119    end Set_Dependents_Fallback_Handler;
120
121    --------------------------
122    -- Set_Specific_Handler --
123    --------------------------
124
125    procedure Set_Specific_Handler
126      (T       : Ada.Task_Identification.Task_Id;
127       Handler : Termination_Handler)
128    is
129    begin
130       --  Tasking_Error is raised if the task identified by T has already
131       --  terminated. Program_Error is raised if the value of T is
132       --  Null_Task_Id.
133
134       if T = Ada.Task_Identification.Null_Task_Id then
135          raise Program_Error;
136       elsif Ada.Task_Identification.Is_Terminated (T) then
137          raise Tasking_Error;
138       else
139          declare
140             Target : constant System.Tasking.Task_Id := To_Task_Id (T);
141
142          begin
143             SSL.Abort_Defer.all;
144
145             if Single_Lock then
146                STPO.Lock_RTS;
147             end if;
148
149             STPO.Write_Lock (Target);
150
151             Target.Common.Specific_Handler := To_ST (Handler);
152
153             STPO.Unlock (Target);
154
155             if Single_Lock then
156                STPO.Unlock_RTS;
157             end if;
158
159             SSL.Abort_Undefer.all;
160          end;
161       end if;
162    end Set_Specific_Handler;
163
164    ----------------------
165    -- Specific_Handler --
166    ----------------------
167
168    function Specific_Handler
169      (T : Ada.Task_Identification.Task_Id) return Termination_Handler
170    is
171    begin
172       --  Tasking_Error is raised if the task identified by T has already
173       --  terminated. Program_Error is raised if the value of T is
174       --  Null_Task_Id.
175
176       if T = Ada.Task_Identification.Null_Task_Id then
177          raise Program_Error;
178       elsif Ada.Task_Identification.Is_Terminated (T) then
179          raise Tasking_Error;
180       else
181          declare
182             Target : constant System.Tasking.Task_Id := To_Task_Id (T);
183             TH     : Termination_Handler;
184
185          begin
186             SSL.Abort_Defer.all;
187
188             if Single_Lock then
189                STPO.Lock_RTS;
190             end if;
191
192             STPO.Write_Lock (Target);
193
194             TH := To_TT (Target.Common.Specific_Handler);
195
196             STPO.Unlock (Target);
197
198             if Single_Lock then
199                STPO.Unlock_RTS;
200             end if;
201
202             SSL.Abort_Undefer.all;
203
204             return TH;
205          end;
206       end if;
207    end Specific_Handler;
208
209 end Ada.Task_Termination;