#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
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);
pragma Assert (Result = 0);
- -- Since the initial signal mask of a thread is inherited from the
- -- creator, and the Environment task has all its signals masked, we
- -- do not need to manipulate caller's signal mask at this point.
- -- All tasks in RTS will have All_Tasks_Mask initially.
+ -- (QMS3263) lists PR 2894086. This defect causes a memory leak when
+ -- pthread_create is interrupted by a signal and later resumed. To avoid
+ -- avoid such a leak the document suggests to disable signals while
+ -- calling pthread_create. The signal mask of the calling thread is
+ -- restored after the call to pthread_create.
-- The write to T.Common.LL.Thread is not racy with regard to the
-- created thread because the created thread will not access it until
-- Restricted.Stages is used). One can verify that by inspecting the
-- Task_Wrapper procedures.
+ Result := Disable_Signals;
+ pragma Assert (Result = 0);
Result := pthread_create
(T.Common.LL.Thread'Access,
Attributes'Access,
Succeeded := Result = 0;
+ Result := Enable_Signals;
+ pragma Assert (Result = 0);
+
Result := pthread_attr_destroy (Attributes'Access);
pragma Assert (Result = 0);
end Create_Task;