Gilles Chanteperdrix wrote:
> Hi,
> 
> here is a patch which implements the idea discussed previously of 
> re-using SIGWINCH to trigger priority changes in user-space. There is 
> only one patch, but the files should have been put in a logical order
> to make review easier.

Thanks for providing this. Find a few comments below, primarily
targeting the (not new) signal hooking strategy.

> 
> Index: include/nucleus/thread.h
> ===================================================================
> --- include/nucleus/thread.h  (revision 4218)
> +++ include/nucleus/thread.h  (working copy)
> @@ -116,6 +116,7 @@
>  #define XNROBBED  0x00000020 /**< Robbed from resource ownership */
>  #define XNATOMIC  0x00000040 /**< In atomic switch from secondary to primary 
> mode */
>  #define XNAFFSET  0x00000080 /**< CPU affinity changed from primary mode */
> +#define XNPRIOSET 0x00000100 /**< Priority changed from primary mode */
>  
>  /* These information flags are available to the real-time interfaces */
>  #define XNTHREAD_INFO_SPARE0  0x10000000
> Index: include/asm-generic/syscall.h
> ===================================================================
> --- include/asm-generic/syscall.h     (revision 4218)
> +++ include/asm-generic/syscall.h     (working copy)
> @@ -59,7 +59,12 @@ typedef struct xnsysinfo {
>      unsigned long tickval;   /* Tick duration (ns) */
>  } xnsysinfo_t;
>  
> -#define SIGHARDEN  SIGWINCH
> +#define SIGSHADOW  SIGWINCH
> +#define SIGSHADOW_ACTION_HARDEN 1
> +#define SIGSHADOW_ACTION_RENICE 2
> +#define sigshadow_action(code) ((code) & 0xff)
> +#define sigshadow_prio(code) (((code) >> 8) & 0xff)
> +#define sigshadow_int(action, prio) ((action) | ((prio) << 8))
>  
>  #ifdef __KERNEL__
>  
> Index: include/nucleus/shadow.h
> ===================================================================
> --- include/nucleus/shadow.h  (revision 4218)
> +++ include/nucleus/shadow.h  (working copy)
> @@ -98,6 +98,7 @@ void xnshadow_reset_shield(void);
>  
>  void xnshadow_send_sig(struct xnthread *thread,
>                      int sig,
> +                    int arg,
>                      int specific);
>  
>  void xnshadow_rpi_check(void);
> Index: ksrc/nucleus/shadow.c
> ===================================================================
> --- ksrc/nucleus/shadow.c     (revision 4218)
> +++ ksrc/nucleus/shadow.c     (working copy)
> @@ -115,6 +115,14 @@ do { \
>     switch_lock_owner[task_cpu(t)] = t; \
>  } while(0)
>  
> +#define xnshadow_sig_mux(sig, arg) ((sig) | (arg << 8))
> +#define xnshadow_sig_demux(muxed, sig, arg) \
> +     do {                                 \
> +             int _muxed = (muxed);        \
> +             (sig) = _muxed & 0xff;       \
> +             (arg) = _muxed << 8;         \
> +     } while (0)
> +
>  static struct task_struct *switch_lock_owner[XNARCH_NR_CPUS];
>  
>  static int nucleus_muxid = -1;
> @@ -879,7 +887,7 @@ static void xnshadow_dereference_skin(un
>  
>  static void lostage_handler(void *cookie)
>  {
> -     int cpu = smp_processor_id(), reqnum, sig;
> +     int cpu = smp_processor_id(), reqnum, sig, arg;
>       struct __lostagerq *rq = &lostagerq[cpu];
>  
>       while ((reqnum = rq->out) != rq->in) {
> @@ -927,8 +935,16 @@ static void lostage_handler(void *cookie
>  
>               case LO_SIGTHR_REQ:
>  
> -                     sig = rq->req[reqnum].arg;
> -                     send_sig(sig, p, 1);
> +                     xnshadow_sig_demux(rq->req[reqnum].arg, sig, arg);
> +                     if (sig == SIGSHADOW) {
> +                             siginfo_t si;
> +                             memset(&si, '\0', sizeof(si));
> +                             si.si_signo = sig;
> +                             si.si_code = SI_QUEUE;
> +                             si.si_int = arg;
> +                             send_sig_info(sig, &si, p);
> +                     } else
> +                             send_sig(sig, p, 1);
>                       break;
>  
>               case LO_SIGGRP_REQ:
> @@ -1235,6 +1251,13 @@ void xnshadow_relax(int notify)
>               /* Help debugging spurious relaxes. */
>               send_sig(SIGXCPU, current, 1);
>  
> +     if (xnthread_test_info(thread, XNPRIOSET)) {
> +             xnthread_clear_info(thread, XNPRIOSET);
> +             xnshadow_send_sig(thread, SIGSHADOW,
> +                               sigshadow_int(SIGSHADOW_ACTION_RENICE, prio),
> +                               1);
> +     }
> +
>  #ifdef CONFIG_SMP
>       /* If the shadow thread changed its CPU affinity while in
>          primary mode, reset the CPU affinity of its Linux
> @@ -1485,13 +1508,13 @@ void xnshadow_start(xnthread_t *thread)
>  void xnshadow_renice(xnthread_t *thread)
>  {
>       /* Called with nklock locked, Xenomai interrupts off. */

I think this comment line should be pushed in front of the function at
this chance.

> -     struct task_struct *p = xnthread_archtcb(thread)->user_task;
> -
>       /* We need to bound the priority values in the [1..MAX_RT_PRIO-1]
>          range, since the core pod's priority scale is a superset of
>          Linux's priority scale. */
>       int prio = normalize_priority(xnthread_current_priority(thread));
> -     schedule_linux_call(LO_RENICE_REQ, p, prio);
> +
> +     xnshadow_send_sig(thread, SIGSHADOW,
> +                       sigshadow_int(SIGSHADOW_ACTION_RENICE, prio), 1);
>  
>       if (!xnthread_test_state(thread, XNDORMANT) &&
>           xnthread_sched(thread) == xnpod_current_sched())
> @@ -1501,8 +1524,7 @@ void xnshadow_renice(xnthread_t *thread)
>  void xnshadow_suspend(xnthread_t *thread)
>  {
>       /* Called with nklock locked, Xenomai interrupts off. */
> -     struct task_struct *p = xnthread_archtcb(thread)->user_task;
> -     schedule_linux_call(LO_SIGTHR_REQ, p, SIGHARDEN);
> +     xnshadow_send_sig(thread, SIGSHADOW, SIGSHADOW_ACTION_HARDEN, 1);
>  }
>  
>  static int xnshadow_sys_migrate(struct pt_regs *regs)
> @@ -1513,7 +1535,7 @@ static int xnshadow_sys_migrate(struct p
>                               return -EPERM;
>  
>                       /* Paranoid: a corner case where the
> -                        user-space side fiddles with SIGHARDEN
> +                        user-space side fiddles with SIGSHADOW
>                          while the target thread is still waiting to
>                          be started. */
>                       if (xnthread_test_state(xnshadow_thread(current), 
> XNDORMANT))
> @@ -1979,10 +2001,11 @@ static inline int substitute_linux_sysca
>       return 0;
>  }
>  
> -void xnshadow_send_sig(xnthread_t *thread, int sig, int specific)
> +void xnshadow_send_sig(xnthread_t *thread, int sig, int arg, int specific)
>  {
>       schedule_linux_call(specific ? LO_SIGTHR_REQ : LO_SIGGRP_REQ,
> -                         xnthread_user_task(thread), sig);
> +                         xnthread_user_task(thread),
> +                         xnshadow_sig_mux(sig, specific ? arg : 0));
>  }
>  
>  static inline int do_hisyscall_event(unsigned event, unsigned domid, void 
> *data)
> Index: ksrc/nucleus/synch.c
> ===================================================================
> --- ksrc/nucleus/synch.c      (revision 4218)
> +++ ksrc/nucleus/synch.c      (working copy)
> @@ -121,6 +121,8 @@ static void xnsynch_renice_thread(xnthre
>  #ifdef CONFIG_XENO_OPT_PERVASIVE
>       if (xnthread_test_state(thread, XNRELAX))
>               xnshadow_renice(thread);
> +     else if (xnthread_test_state(thread, XNSHADOW))
> +             xnthread_set_info(thread, XNPRIOSET);
>  #endif /* CONFIG_XENO_OPT_PERVASIVE */
>  }
>  
> Index: ksrc/nucleus/pod.c
> ===================================================================
> --- ksrc/nucleus/pod.c        (revision 4218)
> +++ ksrc/nucleus/pod.c        (working copy)
> @@ -1162,7 +1162,7 @@ void xnpod_delete_thread(xnthread_t *thr
>           !xnthread_test_state(thread, XNDORMANT) &&
>           !xnpod_current_p(thread)) {
>               if (!xnpod_userspace_p())
> -                     xnshadow_send_sig(thread, SIGKILL, 1);
> +                     xnshadow_send_sig(thread, SIGKILL, 0, 1);
>               /*
>                * Otherwise, assume the interface library has issued
>                * pthread_cancel on the target thread, which should
> @@ -1456,7 +1456,7 @@ void xnpod_suspend_thread(xnthread_t *th
>          is actually running some code under the control of the
>          Linux scheduler (i.e. it's relaxed).  To make this
>          possible, we force the target Linux task to migrate back to
> -        the Xenomai domain by sending it a SIGHARDEN signal the
> +        the Xenomai domain by sending it a SIGSHADOW signal the
>          skin interface libraries trap for this specific internal
>          purpose, whose handler is expected to call back the
>          nucleus's migration service. By forcing this migration, we
> @@ -1821,8 +1821,12 @@ void xnpod_renice_thread_inner(xnthread_
>                       xnpod_resume_thread(thread, 0);
>       }
>  #ifdef CONFIG_XENO_OPT_PERVASIVE
> -     if (propagate && xnthread_test_state(thread, XNRELAX))
> -             xnshadow_renice(thread);
> +     if (propagate) {
> +             if (xnthread_test_state(thread, XNRELAX))
> +                     xnshadow_renice(thread);
> +             else if (xnthread_test_state(thread, XNSHADOW))
> +                     xnthread_set_info(thread, XNPRIOSET);
> +     }
>  #endif /* CONFIG_XENO_OPT_PERVASIVE */
>  
>       xnlock_put_irqrestore(&nklock, s);
> Index: include/asm-generic/bits/sigshadow.h
> ===================================================================
> --- include/asm-generic/bits/sigshadow.h      (revision 0)
> +++ include/asm-generic/bits/sigshadow.h      (revision 0)
> @@ -0,0 +1,72 @@
> +#ifndef _XENO_ASM_GENERIC_BITS_SIGSHADOW_H
> +#define _XENO_ASM_GENERIC_BITS_SIGSHADOW_H
> +
> +#include <pthread.h>
> +#include <signal.h>
> +
> +static pthread_once_t sigshadow_installed = PTHREAD_ONCE_INIT;
> +static struct sigaction old_sigshadow_action;
> +
> +static void sigshadow_handler(int sig, siginfo_t *si, void *ctxt)
> +{
> +     int action;
> +
> +     /* Not a signal sent by Xenomai nucleus */
> +     if (si->si_code != SI_QUEUE) {
> +             const struct sigaction *const sa = &old_sigshadow_action;
> +             sigset_t old_sigset;
> +
> +       not_nucleus:
> +             if ((!(sa->sa_flags & SA_SIGINFO) && !sa->sa_handler)
> +                 || ((sa->sa_flags & SA_SIGINFO) && !sa->sa_sigaction))
> +                     return;
> +
> +             pthread_sigmask(SIG_SETMASK, &sa->sa_mask, &old_sigset);
> +             if (!(sa->sa_flags & SA_SIGINFO))
> +                     sa->sa_handler(sig);
> +             else
> +                     sa->sa_sigaction(sig, si, ctxt);
> +             pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
> +             return;
> +     }
> +
> +     action = sigshadow_action(si->si_int);
> +
> +     switch(action) {
> +     case SIGSHADOW_ACTION_HARDEN:
> +             XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> +             break;
> +
> +     case SIGSHADOW_ACTION_RENICE: {
> +             struct sched_param param;
> +             int policy;
> +
> +             param.sched_priority = sigshadow_prio(si->si_int);
> +             policy = param.sched_priority > 0 ? SCHED_FIFO: SCHED_OTHER;
> +             pthread_setschedparam(pthread_self(), policy, &param);
> +             break;
> +     }
> +
> +     default:
> +             goto not_nucleus;
> +     }
> +}
> +
> +static void sigshadow_install_once(void)
> +{
> +     struct sigaction new_sigshadow_action;
> +
> +     new_sigshadow_action.sa_flags = SA_SIGINFO | SA_RESTART;
> +     new_sigshadow_action.sa_sigaction = sigshadow_handler;
> +     sigemptyset(&new_sigshadow_action.sa_mask);
> +
> +     sigaction(SIGSHADOW, &new_sigshadow_action, &old_sigshadow_action);
> +     if (!(old_sigshadow_action.sa_flags & SA_NODEFER))
> +             sigaddset(&old_sigshadow_action.sa_mask, SIGSHADOW);
> +}
> +
> +static inline void sigshadow_install(void)
> +{
> +     pthread_once(&sigshadow_installed, sigshadow_install_once);
> +}
> +#endif /* _XENO_ASM_GENERIC_BITS_SIGSHADOW_H */

I wonder if we shouldn't switch the signal hooking strategy: So far we
install the handler at shadow thread creation time, saving a potentially
installed handler of the application for redirection of
Xenomai-unrelated events. But that only works if the application
installed the handler before it creates the first shadow thread, right?
If the app decides to install/change the SIGWINCH handler later on
(without taking care of our handler), we will loose.

Suggestion: As this is fragile and cannot be solved transparently, lets
document this signal requirement of Xenomai, e.g. in all task/thread
creation functions of the skins. Tell the user that Xenomai will install
a custom SIGWINCH handler and that, if the app wants to override it, it
has to make sure to _first_ call into a Xenomai-provided handler and
check if that one wants to handle the event. I'm thinking of something
like int xeno_sigwinch_handler(int sig, siginfo_t *si, void *ctxt),
where the return code is non-zero in case the signal was processed.

With this policy in place, we can switch the signal handler installation
above to __attribute__ ((construtor)) and save us all the changes
regarding sigshadow_install below.

> Index: src/skins/posix/thread.c
> ===================================================================
> --- src/skins/posix/thread.c  (revision 4218)
> +++ src/skins/posix/thread.c  (working copy)
> @@ -26,23 +26,13 @@
>  #include <semaphore.h>
>  #include <posix/syscall.h>
>  #include <asm-generic/bits/current.h>
> +#include <asm-generic/bits/sigshadow.h>
>  
>  extern int __pse51_muxid;
>  
>  static pthread_attr_t default_attr;
>  static int linuxthreads;
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void __pthread_sigharden_handler(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &__pthread_sigharden_handler)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  int __wrap_pthread_setschedparam(pthread_t thread,
>                                int policy, const struct sched_param *param)
>  {
> @@ -59,7 +49,7 @@ int __wrap_pthread_setschedparam(pthread
>               __real_pthread_setschedparam(thread, policy, param);
>  
>       if (!err && promoted) {
> -             old_sigharden_handler = signal(SIGHARDEN, 
> &__pthread_sigharden_handler);
> +             sigshadow_install();
>               xeno_set_current();
>               if (policy != SCHED_OTHER)
>                       XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> @@ -118,7 +108,7 @@ static void *__pthread_trampoline(void *
>       int parent_prio, policy;
>       long err;
>  
> -     old_sigharden_handler = signal(SIGHARDEN, &__pthread_sigharden_handler);
> +     sigshadow_install();
>  
>       param.sched_priority = iargs->prio;
>       policy = iargs->policy;
> Index: src/skins/native/task.c
> ===================================================================
> --- src/skins/native/task.c   (revision 4218)
> +++ src/skins/native/task.c   (working copy)
> @@ -26,6 +26,7 @@
>  #include <limits.h>
>  #include <native/syscall.h>
>  #include <native/task.h>
> +#include <asm-generic/bits/sigshadow.h>
>  #include "wrappers.h"
>  
>  extern pthread_key_t __native_tskey;
> @@ -42,17 +43,6 @@ struct rt_task_iargs {
>       xncompletion_t *completionp;
>  };
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void rt_task_sigharden(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &rt_task_sigharden)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  static void *rt_task_trampoline(void *cookie)
>  {
>       struct rt_task_iargs *iargs = (struct rt_task_iargs *)cookie;
> @@ -74,7 +64,7 @@ static void *rt_task_trampoline(void *co
>       /* rt_task_delete requires asynchronous cancellation */
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
>  
> -     old_sigharden_handler = signal(SIGHARDEN, &rt_task_sigharden);
> +     sigshadow_install();
>  
>       bulk.a1 = (u_long)iargs->task;
>       bulk.a2 = (u_long)iargs->name;
> @@ -175,8 +165,7 @@ int rt_task_shadow(RT_TASK *task, const 
>  
>       /* rt_task_delete requires asynchronous cancellation */
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &rt_task_sigharden);
> +     sigshadow_install();
>  
>       if (prio > 0) {
>               /* Make sure the POSIX library caches the right priority. */
> Index: src/skins/vxworks/taskLib.c
> ===================================================================
> --- src/skins/vxworks/taskLib.c       (revision 4218)
> +++ src/skins/vxworks/taskLib.c       (working copy)
> @@ -27,6 +27,7 @@
>  #include <errno.h>
>  #include <limits.h>
>  #include <vxworks/vxworks.h>
> +#include <asm-generic/bits/sigshadow.h>
>  #include "wrappers.h"
>  
>  extern pthread_key_t __vxworks_tskey;
> @@ -54,17 +55,6 @@ struct wind_task_iargs {
>       xncompletion_t *completionp;
>  };
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void wind_task_sigharden(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &wind_task_sigharden)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  static int wind_task_set_posix_priority(int prio, struct sched_param *param)
>  {
>       int maxpprio, pprio;
> @@ -103,8 +93,7 @@ static void *wind_task_trampoline(void *
>  
>       /* wind_task_delete requires asynchronous cancellation */
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &wind_task_sigharden);
> +     sigshadow_install();
>  
>       bulk.a1 = (u_long)iargs->name;
>       bulk.a2 = (u_long)iargs->prio;
> Index: src/skins/psos+/task.c
> ===================================================================
> --- src/skins/psos+/task.c    (revision 4218)
> +++ src/skins/psos+/task.c    (working copy)
> @@ -26,6 +26,7 @@
>  #include <memory.h>
>  #include <string.h>
>  #include <psos+/psos.h>
> +#include <asm-generic/bits/sigshadow.h>
>  
>  extern int __psos_muxid;
>  
> @@ -38,17 +39,6 @@ struct psos_task_iargs {
>       xncompletion_t *completionp;
>  };
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void psos_task_sigharden(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &psos_task_sigharden)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  static int psos_task_set_posix_priority(int prio, struct sched_param *param)
>  {
>       int maxpprio, pprio;
> @@ -79,8 +69,7 @@ static void *psos_task_trampoline(void *
>       pthread_setschedparam(pthread_self(), policy, &param);
>  
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
> +     sigshadow_install();
>  
>       err = XENOMAI_SKINCALL5(__psos_muxid,
>                               __psos_t_create,
> @@ -174,8 +163,7 @@ u_long t_shadow(const char *name, /* Xen
>               u_long *tid_r)
>  {
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
> +     sigshadow_install();
>  
>       return XENOMAI_SKINCALL5(__psos_muxid,
>                                __psos_t_create,
> Index: src/skins/vrtx/task.c
> ===================================================================
> --- src/skins/vrtx/task.c     (revision 4218)
> +++ src/skins/vrtx/task.c     (working copy)
> @@ -27,6 +27,7 @@
>  #include <errno.h>
>  #include <limits.h>
>  #include <vrtx/vrtx.h>
> +#include <asm-generic/bits/sigshadow.h>
>  
>  extern pthread_key_t __vrtx_tskey;
>  
> @@ -44,17 +45,6 @@ struct vrtx_task_iargs {
>       xncompletion_t *completionp;
>  };
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void vrtx_task_sigharden(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &vrtx_task_sigharden)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  static int vrtx_task_set_posix_priority(int prio, struct sched_param *param)
>  {
>       int maxpprio, pprio;
> @@ -93,8 +83,7 @@ static void *vrtx_task_trampoline(void *
>  
>       /* vrtx_task_delete requires asynchronous cancellation */
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &vrtx_task_sigharden);
> +     sigshadow_install();
>  
>       bulk.a1 = (u_long)iargs->tid;
>       bulk.a2 = (u_long)iargs->prio;
> Index: src/skins/uitron/task.c
> ===================================================================
> --- src/skins/uitron/task.c   (revision 4218)
> +++ src/skins/uitron/task.c   (working copy)
> @@ -24,6 +24,7 @@
>  #include <errno.h>
>  #include <limits.h>
>  #include <asm/xenomai/system.h>
> +#include <asm-generic/bits/sigshadow.h>
>  #include <uitron/uitron.h>
>  
>  extern int __uitron_muxid;
> @@ -35,17 +36,6 @@ struct uitron_task_iargs {
>       xncompletion_t *completionp;
>  };
>  
> -static void (*old_sigharden_handler)(int sig);
> -
> -static void uitron_task_sigharden(int sig)
> -{
> -     if (old_sigharden_handler &&
> -         old_sigharden_handler != &uitron_task_sigharden)
> -             old_sigharden_handler(sig);
> -
> -     XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
> -}
> -
>  static int uitron_task_set_posix_priority(int prio, struct sched_param 
> *param)
>  {
>       int maxpprio, pprio;
> @@ -80,7 +70,7 @@ static void *uitron_task_trampoline(void
>       pthread_setschedparam(pthread_self(), policy, &param);
>  
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -     old_sigharden_handler = signal(SIGHARDEN, &uitron_task_sigharden);
> +     sigshadow_install();
>  
>       err = XENOMAI_SKINCALL3(__uitron_muxid,
>                               __uitron_cre_tsk,
> @@ -157,8 +147,7 @@ ER shd_tsk(ID tskid, T_CTSK *pk_ctsk) /*
>       pthread_setschedparam(pthread_self(), policy, &param);
>  
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> -
> -     old_sigharden_handler = signal(SIGHARDEN, &uitron_task_sigharden);
> +     sigshadow_install();
>  
>       return XENOMAI_SKINCALL3(__uitron_muxid,
>                                __uitron_cre_tsk,
> 

One question currently remains open for me, both regarding your approach
as well as my suggestion: What happens if some app links against more
than onw skin library? I think your approach will cause multiple
sigshadow_handler invocations (as the stack up due to library-local
pthread_once), while mine suffers from multiple xeno_sigwinch_handler
symbols. The latter might be solvable with __attribute__ ((weak)), correct?

Jan

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to