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:
ouyangxiangzhen 2024-07-09 10:23:13 +08:00 committed by Xiang Xiao
parent a483c884ce
commit 213d5538fc
3 changed files with 46 additions and 6 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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));