signal: Add support for SIGEV_THREAD_ID and sigev_notify_thread_id
This patch added support for SIGEV_THREAD_ID and sigev_notify_thread_id. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com> Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
a483c884ce
commit
213d5538fc
@ -264,9 +264,11 @@
|
||||
#define SIGEV_NONE 0 /* No asynchronous notification is delivered */
|
||||
#define SIGEV_SIGNAL 1 /* Notify via signal,with an application-defined value */
|
||||
#ifdef CONFIG_SIG_EVTHREAD
|
||||
# define SIGEV_THREAD 3 /* A notification function is called */
|
||||
# define SIGEV_THREAD 2 /* A notification function is called */
|
||||
#endif
|
||||
|
||||
#define SIGEV_THREAD_ID 4 /* Notify a specific thread via signal. */
|
||||
|
||||
/* sigaltstack stack size */
|
||||
|
||||
#define MINSIGSTKSZ CONFIG_PTHREAD_STACK_MIN /* Smallest signal stack size */
|
||||
@ -345,6 +347,8 @@ struct sigevent
|
||||
sigev_notify_function_t sigev_notify_function; /* Notification function */
|
||||
FAR struct pthread_attr_s *sigev_notify_attributes; /* Notification attributes (not used) */
|
||||
#endif
|
||||
|
||||
pid_t sigev_notify_thread_id; /* ID of thread to signal */
|
||||
};
|
||||
|
||||
/* The following types is used to pass parameters to/from signal handlers */
|
||||
|
@ -110,11 +110,9 @@ int nxsig_notification(pid_t pid, FAR struct sigevent *event,
|
||||
|
||||
/* Notify client via a signal? */
|
||||
|
||||
if (event->sigev_notify == SIGEV_SIGNAL)
|
||||
if (event->sigev_notify & SIGEV_SIGNAL)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
#endif
|
||||
siginfo_t info;
|
||||
|
||||
/* Yes.. Create the siginfo structure */
|
||||
@ -135,6 +133,23 @@ int nxsig_notification(pid_t pid, FAR struct sigevent *event,
|
||||
|
||||
memcpy(&info.si_value, &event->sigev_value, sizeof(union sigval));
|
||||
|
||||
/* Used only by POSIX timer. Notice that it is UNSAFE, unless
|
||||
* we GUARANTEE that event->sigev_notify_thread_id is valid.
|
||||
*/
|
||||
|
||||
if (event->sigev_notify & SIGEV_THREAD_ID)
|
||||
{
|
||||
rtcb = nxsched_get_tcb(event->sigev_notify_thread_id);
|
||||
if (rtcb != NULL)
|
||||
{
|
||||
return nxsig_tcbdispatch(rtcb, &info);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the signal */
|
||||
|
||||
return nxsig_dispatch(pid, &info);
|
||||
@ -143,7 +158,7 @@ int nxsig_notification(pid_t pid, FAR struct sigevent *event,
|
||||
#ifdef CONFIG_SIG_EVTHREAD
|
||||
/* Notify the client via a function call */
|
||||
|
||||
else if (event->sigev_notify == SIGEV_THREAD)
|
||||
else if (event->sigev_notify & SIGEV_THREAD)
|
||||
{
|
||||
/* Initialize the work information */
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "timer/timer.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_POSIX_TIMERS
|
||||
@ -158,6 +159,7 @@ int timer_create(clockid_t clockid, FAR struct sigevent *evp,
|
||||
FAR timer_t *timerid)
|
||||
{
|
||||
FAR struct posix_timer_s *ret;
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
|
||||
/* Sanity checks. */
|
||||
|
||||
@ -181,7 +183,7 @@ int timer_create(clockid_t clockid, FAR struct sigevent *evp,
|
||||
|
||||
ret->pt_clock = clockid;
|
||||
ret->pt_crefs = 1;
|
||||
ret->pt_owner = nxsched_getpid();
|
||||
ret->pt_owner = tcb->pid;
|
||||
ret->pt_delay = 0;
|
||||
ret->pt_expected = 0;
|
||||
|
||||
@ -189,6 +191,25 @@ int timer_create(clockid_t clockid, FAR struct sigevent *evp,
|
||||
|
||||
if (evp)
|
||||
{
|
||||
FAR struct tcb_s *ntcb;
|
||||
|
||||
/* Check the SIGEV_THREAD_ID and validate the tid */
|
||||
|
||||
if (evp->sigev_notify & SIGEV_THREAD_ID)
|
||||
{
|
||||
/* Make sure that the notified thread is
|
||||
* in same process with current thread.
|
||||
*/
|
||||
|
||||
ntcb = nxsched_get_tcb(evp->sigev_notify_thread_id);
|
||||
|
||||
if (ntcb == NULL || tcb->group != ntcb->group)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Yes, copy the entire struct sigevent content */
|
||||
|
||||
memcpy(&ret->pt_event, evp, sizeof(struct sigevent));
|
||||
|
Loading…
Reference in New Issue
Block a user