From 4417728955026eb9cf1bbdb6139e962496a370a9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 13 May 2015 14:43:43 -0600 Subject: [PATCH] Re-implemened pthread_kill(). It as just a simple wrapper around kill() but since the correct dispatching of singles for multi-threaded task groups has been implemented, calling kill() does no work. The corrected implementation of pthread_kill() will direct the signal specifically to the specific pthread and no other. --- TODO | 12 +------ sched/pthread/pthread_kill.c | 64 +++++++++++++++++++++++++++++++----- sched/signal/sig_dispatch.c | 1 - sched/signal/sig_kill.c | 2 -- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/TODO b/TODO index bf600e1f1b..4751de5883 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ nuttx/ (11) Task/Scheduler (sched/) (1) Memory Management (mm/) - (4) Signals (sched/signal, arch/) + (3) Signals (sched/signal, arch/) (2) pthreads (sched/pthread) (0) Message Queues (sched/mqueue) (4) C++ Support @@ -307,16 +307,6 @@ o Signals (sched/signal, arch/) Status: Open Priority: Low. Even if there are only 31 usable signals, that is still a lot. - Title: PTHREAD_KILL - Description: Currently pthread_kill() is a simple wrapper around kill(). This is - not correct. kill() will deliver signals to a task group with - incompatible rules. - - "The pthread_kill() function shall request that a signal be delivered - to the specified thread." Reference http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_kill.html - Status: Open - Priority: Medium-Low unless you need this functionality. - o pthreads (sched/pthreads) ^^^^^^^^^^^^^^^^^ diff --git a/sched/pthread/pthread_kill.c b/sched/pthread/pthread_kill.c index 1759f75c8d..cf5d068459 100644 --- a/sched/pthread/pthread_kill.c +++ b/sched/pthread/pthread_kill.c @@ -1,7 +1,7 @@ /************************************************************************ * sched/pthread/pthread_kill.c * - * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,8 +45,10 @@ #include #include +#include "signal/signal.h" + /************************************************************************ - * Global Functions + * Public Functions ************************************************************************/ /************************************************************************ @@ -80,16 +82,60 @@ int pthread_kill(pthread_t thread, int signo) { +#ifdef CONFIG_SCHED_HAVE_PARENT + FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head; +#endif + FAR struct tcb_s *stcb; + siginfo_t info; int ret; - set_errno(EINVAL); - ret = kill((pid_t)thread, signo); - if (ret != OK) + /* Make sure that the signal is valid */ + + if (!GOOD_SIGNO(signo)) { - ret = get_errno(); + ret = -EINVAL; + goto errout; } - return ret; + /* Keep things stationary through the following */ + + sched_lock(); + + /* Create the siginfo structure */ + + info.si_signo = signo; + info.si_code = SI_USER; + info.si_value.sival_ptr = NULL; +#ifdef CONFIG_SCHED_HAVE_PARENT + info.si_pid = rtcb->pid; + info.si_status = OK; +#endif + + /* Get the TCB associated with the thread */ + + stcb = sched_gettcb((pid_t)thread); + if (!stcb) + { + ret = -ESRCH; + goto errout_with_lock; + } + + /* Dispatch the signal to thread, bypassing normal task group thread + * dispatch rules. + */ + + ret = sig_tcbdispatch(stcb, &info); + sched_unlock(); + + if (ret < 0) + { + goto errout; + } + + return OK; + +errout_with_lock: + sched_unlock(); +errout: + return -ret; } - - diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c index 954b4d2cd2..1985fc7f27 100644 --- a/sched/signal/sig_dispatch.c +++ b/sched/signal/sig_dispatch.c @@ -501,4 +501,3 @@ int sig_dispatch(pid_t pid, FAR siginfo_t *info) #endif } - diff --git a/sched/signal/sig_kill.c b/sched/signal/sig_kill.c index 3a65535e74..956029a693 100644 --- a/sched/signal/sig_kill.c +++ b/sched/signal/sig_kill.c @@ -136,5 +136,3 @@ errout: set_errno(-ret); return ERROR; } - -