#ifdef __QNX__
#include <sys/syspage.h>
#include <sys/time.h>
-#include <signal.h>
#endif
#ifdef IN_RTS
*/
}
-#if defined (__QNX__)
-
-static __thread sigset_t set;
-static __thread sigset_t oset;
-static __thread int signals_disabled = 0;
-
-int __gnat_disable_signals(void)
-{
- sigemptyset(&set);
- sigaddset(&set, SIGHUP);
- sigaddset(&set, SIGINT);
- sigaddset(&set, SIGQUIT);
- sigaddset(&set, SIGILL);
- sigaddset(&set, SIGTRAP);
- sigaddset(&set, SIGIOT);
- sigaddset(&set, SIGABRT);
- sigaddset(&set, SIGEMT);
- sigaddset(&set, SIGDEADLK);
- sigaddset(&set, SIGFPE);
- sigaddset(&set, SIGKILL);
- sigaddset(&set, SIGBUS);
- sigaddset(&set, SIGSEGV);
- sigaddset(&set, SIGSYS);
- sigaddset(&set, SIGPIPE);
- sigaddset(&set, SIGALRM);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGUSR1);
- sigaddset(&set, SIGUSR2);
- sigaddset(&set, SIGCHLD);
- sigaddset(&set, SIGCLD);
- sigaddset(&set, SIGPWR);
- sigaddset(&set, SIGWINCH);
- sigaddset(&set, SIGURG);
- sigaddset(&set, SIGPOLL);
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGSTOP);
- sigaddset(&set, SIGTSTP);
- sigaddset(&set, SIGCONT);
- sigaddset(&set, SIGTTIN);
- sigaddset(&set, SIGTTOU);
- sigaddset(&set, SIGVTALRM);
- sigaddset(&set, SIGPROF);
- sigaddset(&set, SIGXCPU);
- sigaddset(&set, SIGXFSZ);
- sigaddset(&set, SIGDOOM);
-
- int ret = sigprocmask(SIG_BLOCK, &set, &oset);
- signals_disabled = !ret;
- return ret;
-}
-
-int __gnat_enable_signals(void)
-{
- if (!signals_disabled) {
- return 0;
- }
- signals_disabled = 0;
- return sigprocmask(SIG_SETMASK, &oset, 0);
-}
-
-#endif
-
#ifdef __cplusplus
}
#endif
Unblocked_Signal_Mask : aliased sigset_t;
-- The set of signals that should unblocked in all tasks
+ Default_Signal_Mask : aliased sigset_t;
+ -- Default signal mask, used to restore signal mask after thread creation
+
+ Default_Signal_Mask_Initialized : Boolean := False;
+ -- Allow to not enable default signals if the default signal mask failed to
+ -- initialize.
+
+ procedure Disable_Signals;
+ -- Disable signals before calling pthread_create to avoid a potential
+ -- memory leak on QNX.
+
+ procedure Enable_Signals;
+ -- Enable signals after pthread_create and in the created task. Since the
+ -- created task inherits the disabled signals from the parent they have to
+ -- be enabled for each task separately.
+
-- The followings are internal configuration constants needed
Next_Serial_Number : Task_Serial_Number := 100;
procedure Enter_Task (Self_ID : Task_Id) is
begin
+ Enable_Signals;
Self_ID.Common.LL.LWP := lwp_self;
Specific.Set (Self_ID);
function Thread_Body_Access is new
Ada.Unchecked_Conversion (System.Address, Thread_Body);
-
- function Disable_Signals return Interfaces.C.int with
- Import,
- Convention => C,
- External_Name => "__gnat_disable_signals";
-
- function Enable_Signals return Interfaces.C.int with
- Import,
- Convention => C,
- External_Name => "__gnat_enable_signals";
-
begin
Adjusted_Stack_Size :=
Interfaces.C.size_t (Stack_Size + Alternate_Stack_Size);
-- Restricted.Stages is used). One can verify that by inspecting the
-- Task_Wrapper procedures.
- Result := Disable_Signals;
- pragma Assert (Result = 0);
+ Disable_Signals;
Result := pthread_create
(T.Common.LL.Thread'Access,
Attributes'Access,
Thread_Body_Access (Wrapper),
To_Address (T));
pragma Assert (Result = 0 or else Result = EAGAIN);
+ Enable_Signals;
Succeeded := Result = 0;
- Result := Enable_Signals;
- pragma Assert (Result = 0);
-
Result := pthread_attr_destroy (Attributes'Access);
pragma Assert (Result = 0);
end Create_Task;
end if;
end loop;
+ Result := pthread_sigmask
+ (SIG_SETMASK, null, Default_Signal_Mask'Access);
+ Default_Signal_Mask_Initialized := Result = 0;
+
-- Initialize the lock used to synchronize chain of all ATCBs
Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
pragma Assert (Result = 0);
end Set_Task_Affinity;
+ ---------------------
+ -- Disable_Signals --
+ ---------------------
+
+ procedure Disable_Signals
+ is
+ Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+ begin
+ -- If the default signal mask is not initialized there is no point in
+ -- disabling signals since we can't enable them again. Not enabling them
+ -- might impact the runtimes functionality so we rather accept the
+ -- possible memory leak.
+ if not Default_Signal_Mask_Initialized then
+ return;
+ end if;
+
+ -- If any of the operations of setting up the signal mask fails we abort
+ -- disabling the signals. The function to enable the signals doesn't
+ -- need to care about this. It will simply restore the default signal
+ -- mask if it was successfully initialized. If the signals are not
+ -- disabled this is a no-op.
+ Result := sigemptyset (Set'Access);
+ if Result /= 0 then
+ return;
+ end if;
+ for S in SIGHUP .. SIGXFSZ loop
+ Result := sigaddset (Set'Access, Signal (S));
+ if Result /= 0 then
+ return;
+ end if;
+ end loop;
+ Result := pthread_sigmask (SIG_BLOCK, Set'Access, null);
+ pragma Assert (Result = 0);
+ end Disable_Signals;
+
+ --------------------
+ -- Enable_Signals --
+ --------------------
+
+ procedure Enable_Signals
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Default_Signal_Mask_Initialized then
+ return;
+ end if;
+ Result := pthread_sigmask
+ (SIG_SETMASK, Default_Signal_Mask'Access, null);
+ pragma Assert (Result = 0);
+ end Enable_Signals;
+
end System.Task_Primitives.Operations;