Module: xenomai-head
Branch: master
Commit: 622ea462dc28f464448a9181adc8f98b27a0cd16
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=622ea462dc28f464448a9181adc8f98b27a0cd16

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat Oct 23 12:04:51 2010 +0200

posix: introduce SIGRELS pseudo-signal

In addition to SIGSUSP/SIGRESM, we also need a signal to forcibly
unblock pending threads.

This patch introduces SIGRELS for this purpose.

---

 include/posix/signal.h    |   15 ++++++-----
 ksrc/skins/posix/signal.c |   57 ++++++++++++++++++++++++++++----------------
 2 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/include/posix/signal.h b/include/posix/signal.h
index 78a6b93..4efbf13 100644
--- a/include/posix/signal.h
+++ b/include/posix/signal.h
@@ -116,15 +116,16 @@ int pthread_sigqueue_np (struct pse51_thread *thread, int 
sig, union sigval valu
 
 /*
  * Those are pseudo-signals only available with pthread_kill() to
- * suspend/resume threads synchronously via the low-level nucleus
- * interface. Can't block them, queue them, or even set them in a
- * sigset. Those are nasty, strictly anti-POSIX things; we do provide
- * them nevertheless only because we are mean people doing harmful
- * code for no valid reason. Can't go against your nature, right?
- * Nah... (this said, don't blame us for POSIX, we are not _that_
- * mean).
+ * suspend/resume/unblock threads synchronously via the low-level
+ * nucleus interface. Can't block them, queue them, or even set them
+ * in a sigset. Those are nasty, strictly anti-POSIX things; we do
+ * provide them nevertheless only because we are mean people doing
+ * harmful code for no valid reason. Can't go against your nature,
+ * right?  Nah... (this said, don't blame us for POSIX, we are not
+ * _that_ mean).
  */
 #define SIGSUSP (SIGRTMAX + 1)
 #define SIGRESM (SIGRTMAX + 2)
+#define SIGRELS (SIGRTMAX + 3)
 
 #endif /* _XENO_POSIX_SIGNAL_H */
diff --git a/ksrc/skins/posix/signal.c b/ksrc/skins/posix/signal.c
index 4ab27d6..59acf1e 100644
--- a/ksrc/skins/posix/signal.c
+++ b/ksrc/skins/posix/signal.c
@@ -527,12 +527,24 @@ int sigaction(int sig, const struct sigaction *act, 
struct sigaction *oact)
 int pthread_kill(pthread_t thread, int sig)
 {
        pse51_siginfo_t *si = NULL;
+       int ret = 0;
        spl_t s;
 
+       xnlock_get_irqsave(&nklock, s);
+
+       if (!pse51_obj_active(thread, PSE51_THREAD_MAGIC, struct pse51_thread)) 
{
+               ret = ESRCH;
+               goto unlock_and_exit;
+       }
+
+       if (sig == 0)
+               /* Test for existence -- take fast path. */
+               goto unlock_and_exit;
+
        /*
-        * Undocumented pseudo-signals to suspend and resume threads
-        * via the low-level nucleus services. Process them early,
-        * before anyone can notice...
+        * Undocumented pseudo-signals to suspend/resume/unblock
+        * threads via the low-level nucleus services. Process them
+        * early, before anyone can notice...
         */
        if (sig == SIGSUSP) {
                /*
@@ -543,36 +555,39 @@ int pthread_kill(pthread_t thread, int sig)
                                     XN_INFINITE, XN_RELATIVE, NULL);
                if (&thread->threadbase == xnpod_current_thread() &&
                    xnthread_test_info(&thread->threadbase, XNBREAK))
-                       return -EINTR;
-               return 0;
-       } else if (sig == SIGRESM) {
-               xnpod_resume_thread(&thread->threadbase, XNSUSP);
-               return 0;
+                       ret = EINTR;
+               goto unlock_and_exit;
        }
 
-       if ((unsigned)sig > SIGRTMAX)
-               return EINVAL;
-
-       if (sig) {
-               si = pse51_new_siginfo(sig, SI_USER, (union sigval)0);
+       if (sig == SIGRESM) {
+               xnpod_resume_thread(&thread->threadbase, XNSUSP);
+               goto unlock_and_exit;
+       }
 
-               if (!si)
-                       return EAGAIN;
+       if (sig == SIGRELS) {
+               xnpod_unblock_thread(&thread->threadbase);
+               goto unlock_and_exit;
        }
 
-       xnlock_get_irqsave(&nklock, s);
+       if ((unsigned)sig > SIGRTMAX) {
+               ret = EINVAL;
+               goto unlock_and_exit;
+       }
 
-       if (!pse51_obj_active(thread, PSE51_THREAD_MAGIC, struct pse51_thread)) 
{
-               xnlock_put_irqrestore(&nklock, s);
-               return ESRCH;
+       si = pse51_new_siginfo(sig, SI_USER, (union sigval)0);
+       if (si == NULL) {
+               ret = EAGAIN;
+               goto unlock_and_exit;
        }
 
-       if (sig && pse51_sigqueue_inner(thread, si))
+       if (pse51_sigqueue_inner(thread, si))
                xnpod_schedule();
 
+ unlock_and_exit:
+
        xnlock_put_irqrestore(&nklock, s);
 
-       return 0;
+       return ret;
 }
 
 /**


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

Reply via email to