------------------------------------------------------------------------------
--                                                                          --
--                 GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS               --
--                                                                          --
--                         S Y S T E M . S I G N A L S                      --
--                                                                          --
--                                  B o d y                                 --
--                                                                          --
--                             $Revision: 1.18 $                            --
--                                                                          --
--       Copyright (c) 1991,1992,1993,1994, FSU, All Rights Reserved        --
--                                                                          --
-- GNARL is free software; you can redistribute it  and/or modify it  under --
-- terms  of  the  GNU  Library General Public License  as published by the --
-- Free Software  Foundation;  either version 2, or (at  your  option)  any --
-- later  version.  GNARL is distributed  in the hope that  it will be use- --
-- ful, but but WITHOUT ANY WARRANTY;  without even the implied warranty of --
-- MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Gen- --
-- eral Library Public License  for more details.  You should have received --
-- a  copy of the GNU Library General Public License along with GNARL;  see --
-- file COPYING.LIB.  If not,  write to the  Free Software Foundation,  675 --
-- Mass Ave, Cambridge, MA 02139, USA.                                      --
--                                                                          --
------------------------------------------------------------------------------

--  This package does not follow the GNARL/GNULL layering. It uses both GNARL
--  and GNULL packages without a clear layer in between.

--  Full Dot5 sementics are not fully implemented yet.
--  To be reconsidered ???

with System.Storage_Elements;
with System.Task_Primitives; use System.Task_Primitives;
with System.Tasking.Utilities;
with System.Tasking.Rendezvous;
with Interfaces.C.POSIX_Error;
with Interfaces.C.Pthreads;

package body System.Signals is

   package RTE renames Interfaces.c.POSIX_RTE;
   package POSIX_Error renames Interfaces.C.POSIX_Error;

   Failure : Interfaces.C.POSIX_Error.Return_Code
      renames Interfaces.C.POSIX_Error.Failure;

   Max_Signal : constant := RTE.NSIG;

   subtype Signal_Index is RTE.Signal range 1 .. Max_Signal - 1;

   type Signal_Entry_Assoc is record
      T : Tasking.Task_ID;
      E : Tasking.Task_Entry_Index;
   end record;

   Null_Signal_Entry_Assoc : constant Signal_Entry_Assoc :=
     Signal_Entry_Assoc'
       (T => Tasking.Null_Task, E => Tasking.Null_Task_Entry);

   User_Handler_Table : array (Signal_Index) of Signal_Entry_Assoc
     := (others => Null_Signal_Entry_Assoc);

   type Server_Info is record
      Task_ID : Tasking.Task_ID;  --  Indivisual signal handling task's Task_ID
      Blocked : boolean;          --  Process level Blocking Indication
      Ignored : boolean;          --  Process level Ignoring Indication
      Asynchronous : boolean;     --  Only Asynchronous signals may have
   end record;                    --  user level handler

   type Signal_Server_Array is array (Signal_Index) of Server_Info;

   Signal_Server_Table : Signal_Server_Array;

   task type Handler_Task (S : RTE.Signal);
   type Handler_Task_Access is access Handler_Task;

   Handler_Access : array (Signal_Index) of  Handler_Task_Access;

   task Signal_Manager is
      entry Bind_Handler   (T : Tasking.Task_ID;
                            E : Tasking.Task_Entry_Index;
                            S : RTE.Signal);
      entry Unbind_Handler (T : Tasking.Task_ID);
      entry Block_Signal   (S : RTE.Signal);
      entry Unblock_Signal (S : RTE.Signal);
   end Signal_Manager;

   M : array (Signal_Index) of Lock;

   C : array (Signal_Index) of Condition_Variable;

   function Address_To_Pointer is new
     Unchecked_Conversion (System.Address, RTE.sigaction_ptr);

   function Address_To_Signal (A : System.Address) return RTE.Signal;

   function Address_To_Signal (A : System.Address) return RTE.Signal is
   begin
      return RTE.Signal (Storage_Elements.To_Integer (A));
   end Address_To_Signal;

   function Address_To_Pointer is new
     Unchecked_Conversion (System.Address, RTE.sigset_t_ptr);

   --  local procedures

   -----------------------
   -- Handler_Installed --
   -----------------------

   function Handler_Installed (S : RTE.Signal) return boolean;

   ----------------------
   -- Server_Installed --
   ----------------------

   function Server_Installed (S : RTE.Signal) return boolean;

   -----------------
   -- Signal_Task --
   -----------------

   procedure Signal_Task (T : Tasking.Task_ID; S : RTE.Signal);

   -------------------------
   -- Thread_Block_Signal --
   -------------------------

   procedure Thread_Block_Signal (S : RTE.Signal);

   ---------------------------
   -- Thread_Unblock_Signal --
   ---------------------------

   procedure Thread_Unblock_Signal (S : RTE.Signal);

   -------------------------
   -- Asynchronous_Signal --
   -------------------------

   function Asynchronous_Signal (S : RTE.Signal) return boolean;

   -------------------------
   -- Initialize_Blocking --
   -------------------------

   procedure Initialize_Blocking;

   ------------------------
   -- Unmask_All_Signals --
   ------------------------

   procedure Unmask_All_Signals;

   ----------------------------
   -- Is_Blocked_Unprotected --
   ----------------------------

   function Is_Blocked_Unprotected
     (S : Interfaces.C.POSIX_RTE.Signal) return boolean;

   ----------------------------
   -- Is_Ignored_Unprotected --
   ----------------------------

   function Is_Ignored_Unprotected
     (S : Interfaces.C.POSIX_RTE.Signal) return boolean;

   ------------------------------
   -- Init_Signal_Server_Table --
   ------------------------------

   procedure Init_Signal_Server_Table;

   --  end of local procedure declaratoins.


   task body Signal_Manager is
      Action : aliased RTE.struct_sigaction;
      Oact   : aliased RTE.struct_sigaction;
      Result : Interfaces.C.POSIX_Error.Return_Code;
      Ceiling_Violation : boolean;
   begin
      Unmask_All_Signals;
      --  initially unmask Ref (boundable) signals for which we want
      --  the default action

      Initialize_Blocking;
      --  update the Block_Table to reflect the process level blocked signals

      loop
         select
         accept Bind_Handler (T : Tasking.Task_ID;
                       E : Tasking.Task_Entry_Index;
                       S : RTE.Signal) do

            Cond_Signal (C (S));
            --  we have installed a handler before we called this entry.
            --  if the Handler Task is waiting to be woke up, do it here.

            if not Is_Blocked_Unprotected (S) then
               Thread_Block_Signal (S);
            end if;
            --  This is the case where signal is not blocked and
            --  handler is installed. We want the handler to catch
            --  signal through sigwait. So mask the signal for this
            --  task.

         end Bind_Handler;

         or accept Unbind_Handler (T : Tasking.Task_ID) do

            for I in Signal_Index loop
               Write_Lock (M (I), Ceiling_Violation);
               if User_Handler_Table (I).T = T then
                  User_Handler_Table (I) := Null_Signal_Entry_Assoc;
                  RTE.sigaction (I, Action'Access, Result);
                  pragma Assert (Result /= Failure or else
                    Utilities.Runtime_Assert_Shutdown (
                      "Signals Failure---sigaction"));
                  --  restore the default action in case sigwait ruined it

                  if Is_Ignored_Unprotected (I) then
                     Action.sa_handler :=
                        Storage_Elements.To_Address (RTE.SIG_IGN);
                  else
                     Action.sa_handler :=
                        Storage_Elements.To_Address (RTE.SIG_DFL);
                  end if;

                  RTE.sigaction (I, Action'Access, Oact'Access, Result);
                  pragma Assert (Result /= Failure or else
                    Utilities.Runtime_Assert_Shutdown (
                      "Signals Failure---sigaction"));

                  if not Is_Blocked_Unprotected (I) then
                     --  this is the case where the handler is waiting for
                     --  sigwait. We have to wake this up and make it to
                     --  wait on condition variable. Also.
                     --  unmask the signal to allow the default action again

                     Signal_Task (Signal_Server_Table (I).Task_ID, I);
                     Thread_Unblock_Signal (I);
                  end if;
               end if;
               Unlock (M (I));
            end loop;

         end Unbind_Handler;

         or accept Block_Signal (S : RTE.Signal) do
            --  caller holds mutex M (S)
            Thread_Block_Signal (S);
         end Block_Signal;

         or accept Unblock_Signal (S : RTE.Signal) do
            --  caller holds mutex M (S)
            Thread_Unblock_Signal (S);
         end Unblock_Signal;

         or terminate;

         end select;

      end loop;
   end Signal_Manager;

   task body Handler_Task is
      Action         : aliased RTE.struct_sigaction;
      Sigwait_Mask   : aliased RTE.Signal_Set;
      Sigwait_Signal : RTE.Signal;
      Result         : Interfaces.C.POSIX_Error.Return_Code;
      Ceiling_Violation : boolean;
   begin
      Tasking.Utilities.Make_Independent;
      --  By making this task independent of master, when the process goes away
      --  handler will be terminated gracefully.

      Write_Lock  (M (S), Ceiling_Violation);

      Signal_Server_Table (S).Task_ID := Tasking.Self;
      --  Register the ID of this task so that other can explicitly
      --  send a signal to this task (thread) using pthread_kill

      RTE.sigemptyset (Sigwait_Mask'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigemptyset"));
      RTE.sigaddset (Sigwait_Mask'Access, S, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));

      loop
         if Is_Blocked_Unprotected (S) or else not Handler_Installed (S) then
            Cond_Wait  (C (S), M (S));
            --  This is the place where we have to take the
            --  default action if the signal is not blocked and there is
            --  no handler installed.

            --  wait for Unblock or Bind operation
         else --  wait for actual signal
            Unlock (M (S));

            Interfaces.C.Pthreads.sigwait
               (Sigwait_Mask, Sigwait_Signal, Result);
            pragma Assert (Result /= Failure or else
              Utilities.Runtime_Assert_Shutdown ("GNULLI failure---sigwait"));

            Write_Lock (M (S), Ceiling_Violation);
            if not Is_Blocked_Unprotected (S) and then
              Handler_Installed (S) and then
              not Is_Ignored_Unprotected (S)
            then
               Unlock (M (S));
               Tasking.Rendezvous.Call_Simple
                 (User_Handler_Table (S).T, User_Handler_Table (S).E,
                  System.Null_Address);
               Write_Lock (M (S), Ceiling_Violation);
            end if;
         end if;
      end loop;
      Unlock (M (S));
   end Handler_Task;

   --------------------------
   -- Bind_Signal_To_Entry --
   --------------------------

   procedure Bind_Signal_To_Entry (T : Tasking.Task_ID;
                          E : Tasking.Task_Entry_Index;
                          Sig : System.Address) is
      S : RTE.Signal := Address_To_Signal (Sig);
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);

      if not Asynchronous_Signal (S) then
         raise Program_Error;
      end if;

      if Handler_Installed (S) then raise Program_Error; end if;
      --  User should not try to redefine handler before explicitly
      --  detaching it

      if not Server_Installed (S) then
         Handler_Access (S) := new Handler_Task (S);
      end if;
      --  Invoke a corresponding Handler_Task

      User_Handler_Table (S) := Signal_Entry_Assoc' (T => T, E => E);

      Unlock (M (S));

      Signal_Manager.Bind_Handler (T, E, S);
   end Bind_Signal_To_Entry;

   --------------------
   -- Detach_Handler --
   --------------------

   procedure Detach_Handler (T : Tasking.Task_ID) is
   begin
      Signal_Manager.Unbind_Handler (T);
   end Detach_Handler;

   ------------------
   -- Block_Signal --
   ------------------

   procedure Block_Signal (S : RTE.Signal) is
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      if not Is_Blocked_Unprotected (S) then
         Signal_Server_Table (S).Blocked := true;
         if Handler_Installed (S) then
            Signal_Task (Signal_Server_Table (S).Task_ID, S);
         else
            Signal_Manager.Block_Signal (S);
         end if;
      end if;
      Unlock (M (S));
   end Block_Signal;

   ---------------------
   -- Unlock_Signal --
   ---------------------

   procedure Unblock_Signal (S : RTE.Signal) is
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      if Is_Blocked_Unprotected (S) then
         Signal_Server_Table (S).Blocked := false;
         if Handler_Installed (S) then
            Cond_Signal (C (S));
            --  should make this to wait on sigwait instead cond variable
         else
            Signal_Manager.Unblock_Signal (S);
         end if;
      end if;
      Unlock (M (S));
   end Unblock_Signal;

   ----------------
   -- Is_Blocked --
   ----------------

   function Is_Blocked (S : Interfaces.C.POSIX_RTE.Signal) return boolean is
      Tmp : boolean;
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      Tmp :=  Signal_Server_Table (S).Blocked;
      Unlock (M (S));
      return Tmp;
   end Is_Blocked;

   ----------------
   -- Is_Ignored --
   ----------------

   function Is_Ignored (S : Interfaces.C.POSIX_RTE.Signal) return boolean is
      Tmp : boolean;
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      Tmp := Signal_Server_Table (S).Ignored;
      Unlock (M (S));
      return Tmp;
   end Is_Ignored;


   -------------------
   -- Ignore_Signal --
   -------------------

   procedure Ignore_Signal (S : RTE.Signal) is
      Action : aliased RTE.struct_sigaction;
      Oact   : aliased RTE.struct_sigaction;
      Result : Interfaces.C.POSIX_Error.Return_Code;
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      if not Is_Ignored_Unprotected (S) then
         RTE.sigaction (S, Action'Access, Result);
         Action.sa_handler := Storage_Elements.To_Address (RTE.SIG_IGN);
         RTE.sigaction (S, Action'Access, Oact'Access, Result);
         pragma Assert (Result /= Failure or else
           Utilities.Runtime_Assert_Shutdown ("Signals Failure---sigaction"));
         Signal_Server_Table (S).Ignored := true;
      end if;
      Unlock (M (S));
   end Ignore_Signal;

   ---------------------
   -- Unignore_Signal --
   ---------------------

   procedure Unignore_Signal (S : RTE.Signal) is
      Action : aliased RTE.struct_sigaction;
      Oact   : aliased RTE.struct_sigaction;
      Result : Interfaces.C.POSIX_Error.Return_Code;
      Ceiling_Violation : boolean;
   begin
      Write_Lock (M (S), Ceiling_Violation);
      if Is_Ignored_Unprotected (S) then
         RTE.sigaction (S, Action'Access, Result);
         Action.sa_handler := Storage_Elements.To_Address (RTE.SIG_DFL);
         RTE.sigaction (S, Action'Access, Oact'Access, Result);
         pragma Assert (Result /= Failure or else
           Utilities.Runtime_Assert_Shutdown ("Signals Failure---sigaction"));
         Signal_Server_Table (S).Ignored := false;
      end if;
      Unlock (M (S));
   end Unignore_Signal;

   -----------------------
   -- Handler_Installed --
   -----------------------

   function Handler_Installed (S : RTE.Signal) return boolean is
   begin
      return User_Handler_Table (S) /= Null_Signal_Entry_Assoc;
   end Handler_Installed;

   ----------------------
   -- Server_Installed --
   ----------------------

   function Server_Installed (S : RTE.Signal) return boolean is
   begin
      return Signal_Server_Table (S).Task_ID /= Tasking.Null_Task;
   end Server_Installed;

   -------------------
   --  Signal_Task  --
   -------------------

   procedure Signal_Task (T : Tasking.Task_ID; S : RTE.Signal) is

      type ATCB_Ptr is access Tasking.Ada_Task_Control_Block;

      function Task_ID_To_ATCB_Ptr is new
        Unchecked_Conversion (Tasking.Task_ID, ATCB_Ptr);

      T_Access : Task_Primitives.TCB_Ptr :=
        Task_ID_To_ATCB_Ptr (T).LL_TCB'Access;
      Result : Interfaces.C.POSIX_Error.Return_Code;
   begin
      Interfaces.C.Pthreads.pthread_kill
         (T_Access.Thread, S, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("GNULLI failure---pthread_kill"));
   end Signal_Task;

   -------------------------
   -- Thread_Block_Signal --
   -------------------------

   procedure Thread_Block_Signal (S : RTE.Signal) is
      Signal_Mask, Old_Set : aliased RTE.Signal_Set;
      Result : Interfaces.C.POSIX_Error.Return_Code;
   begin
      RTE.sigemptyset (Signal_Mask'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigemptyset"));
      RTE.sigaddset (Signal_Mask'Access, S, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigprocmask (
        RTE.SIG_BLOCK, Signal_Mask'Access, Old_Set'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("GNULLI failure---sigprocmask"));
   end Thread_Block_Signal;

   ---------------------------
   -- Thread_Unblock_Signal --
   ---------------------------

   procedure Thread_Unblock_Signal (S : RTE.Signal) is
      Signal_Mask, Old_Set : aliased RTE.Signal_Set;
      Result : Interfaces.C.POSIX_Error.Return_Code;
   begin
      RTE.sigemptyset (Signal_Mask'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigemptyset"));
      RTE.sigaddset (Signal_Mask'Access, S, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigprocmask (
        RTE.SIG_UNBLOCK, Signal_Mask'Access, Old_Set'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("GNULLI failure---sigprocmask"));
   end Thread_Unblock_Signal;

   -------------------------
   -- Asynchronous_Signal --
   -------------------------

   function Asynchronous_Signal (S : RTE.Signal) return boolean is
   begin
      return Signal_Server_Table (S).Asynchronous;
   end Asynchronous_Signal;

   -------------------------
   -- Initialize_Blocking --
   -------------------------

   procedure Initialize_Blocking is
      Signal_Mask, Old_Set : aliased RTE.Signal_Set;
      Result : Interfaces.C.POSIX_Error.Return_Code;
   begin
      RTE.sigprocmask (RTE.SIG_BLOCK, null, Signal_Mask'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals Failure---sigprocmask"));
      for I in Signal_Index loop
         if RTE.sigismember (Signal_Mask'Access, I) = 1 then
            Signal_Server_Table (I).Blocked := true;
         end if;
      end loop;
   end Initialize_Blocking;

   ------------------------
   -- Unmask_All_Signals --
   ------------------------

   --  Unmask asynchronous signals for calling thread.

   procedure Unmask_All_Signals is
      Signal_Mask, Old_Set : aliased RTE.Signal_Set;
      Result : Interfaces.C.POSIX_Error.Return_Code;
   begin
      RTE.sigemptyset (Signal_Mask'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigemptyset"));
      --  RTE.sigaddset (Signal_Mask'Access, RTE.SIGABRT, Result);
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGHUP, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGINT, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGPIPE, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGQUIT, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGTERM, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      --  RTE.sigaddset (Signal_Mask'Access, RTE.SIGUSR1, Result);
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGUSR2, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGCHLD, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGCONT, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGTSTP, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGTTIN, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      RTE.sigaddset (Signal_Mask'Access, RTE.SIGTTOU, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));


      --  Unmask OS specific Asynchronous signals

      for i in RTE.OS_Specific_Async_Signals'First + 1 ..
        RTE.OS_Specific_Async_Signals'Last loop
         RTE.sigaddset
           (Signal_Mask'Access, RTE.OS_Specific_Async_Signals (i), Result);
         pragma Assert (Result /= Failure or else
           Utilities.Runtime_Assert_Shutdown ("Signals failure---sigaddset"));
      end loop;

      RTE.sigprocmask (
        RTE.SIG_UNBLOCK, Signal_Mask'Access, Old_Set'Access, Result);
      pragma Assert (Result /= Failure or else
        Utilities.Runtime_Assert_Shutdown ("Signals Failure---sigprocmask"));
   end Unmask_All_Signals;

   ----------------------------
   -- Is_Blocked_Unprotected --
   ----------------------------

   function Is_Blocked_Unprotected
     (S : Interfaces.C.POSIX_RTE.Signal) return boolean is
   begin
      return Signal_Server_Table (S).Blocked;
   end Is_Blocked_Unprotected;

   ----------------------------
   -- Is_Ignored_Unprotected --
   ----------------------------

   function Is_Ignored_Unprotected
     (S : Interfaces.C.POSIX_RTE.Signal) return boolean is
   begin
      return Signal_Server_Table (S).Ignored;
   end Is_Ignored_Unprotected;

   ------------------------------
   -- Init_Signal_Server_Table --
   ------------------------------

   procedure Init_Signal_Server_Table is
   begin
      Signal_Server_Table := Signal_Server_Array'
        (RTE.SIGKILL | RTE.SIGSTOP | RTE.SIGALRM | RTE.SIGILL | RTE.SIGFPE |
         RTE.SIGSEGV |
         RTE.SIGABRT | RTE.SIGUSR1
         --  These two signals are asynchronous signals according to POSIX
         => (Task_ID      => Tasking.Null_Task,
             Blocked      => false,
             Ignored      => false,
             Asynchronous => false),
         others
         => (Task_ID      => Tasking.Null_Task,
             Blocked      => false,
             Ignored      => false,
             Asynchronous => true));

      --  Reflect OS specific Synchronous signals
      for i in RTE.OS_Specific_Sync_Signals'First + 1 ..
        RTE.OS_Specific_Sync_Signals'Last loop
         Signal_Server_Table (RTE.OS_Specific_Sync_Signals (i)) :=
            Server_Info' (Task_ID      => Tasking.Null_Task,
                          Blocked      => false,
                          Ignored      => false,
                          Asynchronous => false);
      end loop;
   end Init_Signal_Server_Table;
begin
   Init_Signal_Server_Table;
end System.Signals;
