diff --git a/fs/aio/aio_signal.c b/fs/aio/aio_signal.c index c1a50974ec0..2fe002cd643 100644 --- a/fs/aio/aio_signal.c +++ b/fs/aio/aio_signal.c @@ -1,7 +1,7 @@ /**************************************************************************** * fs/aio/aio_signal.c * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2015, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -91,34 +91,12 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp) /* Signal the client */ - if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) + ret = nxsig_notification(pid, &aiocbp->aio_sigevent, SI_ASYNCIO); + if (ret < 0) { -#ifdef CONFIG_CAN_PASS_STRUCTS - ret = nxsig_queue(pid, aiocbp->aio_sigevent.sigev_signo, - aiocbp->aio_sigevent.sigev_value); -#else - ret = nxsig_queue(pid, aiocbp->aio_sigevent.sigev_sign, - aiocbp->aio_sigevent.sigev_value.sival_ptr); -#endif - if (ret < 0) - { - ferr("ERROR: nxsig_queue #1 failed: %d\n", ret); - } + ferr("ERROR: nxsig_notification failed: %d\n", ret); } -#ifdef CONFIG_SIG_EVTHREAD - /* Notify the client via a function call */ - - else if (aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD) - { - ret = nxsig_evthread(pid, &aiocbp->aio_sigevent); - if (ret < 0) - { - ferr("ERROR: nxsig_evthread failed: %d\n", ret); - } - } -#endif - /* Send the poll signal in any event in case the caller is waiting * on sig_suspend(); */ diff --git a/include/nuttx/signal.h b/include/nuttx/signal.h index 5e6d89f0889..83bc4e7863e 100644 --- a/include/nuttx/signal.h +++ b/include/nuttx/signal.h @@ -453,8 +453,6 @@ int nxsig_usleep(useconds_t usec); * ****************************************************************************/ -#if defined(CONFIG_SIG_EVTHREAD) && defined(CONFIG_BUILD_FLAT) -int nxsig_evthread(pid_t pid, FAR struct sigevent *event); -#endif +int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code); #endif /* __INCLUDE_NUTTX_SIGNAL_H */ diff --git a/libs/libc/aio/lio_listio.c b/libs/libc/aio/lio_listio.c index 89f9f573541..4703a888f8c 100644 --- a/libs/libc/aio/lio_listio.c +++ b/libs/libc/aio/lio_listio.c @@ -1,7 +1,7 @@ /**************************************************************************** * libs/libc/aio/lio_listio.c * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2015, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -191,25 +191,8 @@ static void lio_sighandler(int signo, siginfo_t *info, void *ucontext) /* Signal the client */ - if (sighand->sig->sigev_notify == SIGEV_SIGNAL) - { -#ifdef CONFIG_CAN_PASS_STRUCTS - DEBUGASSERT(sigqueue(sighand->pid, sighand->sig->sigev_signo, - sighand->sig->sigev_value)); -#else - DEBUGASSERT(sigqueue(sighand->pid, sighand->sig->sigev_signo, - sighand->sig->sigev_value.sival_ptr)); -#endif - } - -#ifdef CONFIG_SIG_EVTHREAD - /* Notify the client via a function call */ - - else if (ighand->sig->sigev_notify == SIGEV_THREAD) - { - DEBUGASSERT(nxsig_evthread(sighand->pid, &sighand->sig)); - } -#endif + DEBUGVERIFY(nxsig_notification(sighand->pid, &sighand->sig, + SI_ASYNCIO)); /* And free the container */ @@ -303,7 +286,8 @@ static int lio_sigsetup(FAR struct aiocb * const *list, int nent, /* Attach our signal handler */ - printf("waiter_main: Registering signal handler\n"); + finfo("Registering signal handler\n"); + act.sa_sigaction = lio_sighandler; act.sa_flags = SA_SIGINFO; @@ -314,7 +298,9 @@ static int lio_sigsetup(FAR struct aiocb * const *list, int nent, if (status != OK) { int errcode = get_errno(); + ferr("ERROR sigaction failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); return -errcode; } @@ -374,11 +360,12 @@ static int lio_waitall(FAR struct aiocb * const *list, int nent) ret = sigwaitinfo(&set, NULL); if (ret < 0) { + int errcode = get_errno(); + /* The most likely reason that we would get here is because some * unrelated signal has been received. */ - int errcode = get_errno(); ferr("ERROR: sigwaitinfo failed: %d\n", errcode); DEBUGASSERT(errcode > 0); return -errcode; @@ -670,7 +657,7 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, * caller ourself? */ - else if (sig && sig->sigev_notify == SIGEV_SIGNAL) + else if (sig == NULL) { if (nqueued > 0) { @@ -689,43 +676,20 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent, } else { -#ifdef CONFIG_CAN_PASS_STRUCTS - status = sigqueue(getpid(), sig->sigev_signo, - sig->sigev_value); -#else - status = sigqueue(getpid(), sig->sigev_signo, - sig->sigev_value.sival_ptr); -#endif + status = nxsig_notification(sighand->pid, &sighand->sig, + SI_ASYNCIO); if (status < 0 && ret == OK) { - /* Something bad happened while signalling ourself and this is - * the first error to be reported. + /* Something bad happened while performing the notification + * and this is the first error to be reported. */ - retcode = get_errno(); - ret = ERROR; + retcode = -status; + ret = ERROR; } } } -#ifdef CONFIG_SIG_EVTHREAD - /* Notify the client via a function call */ - - else if (sig && sig->sigev_notify == SIGEV_THREAD) - { - status = nxsig_evthread(sighand->pid, &sighand->sig); - if (status < 0 && ret == OK) - { - /* Something bad happened while performing the notification - * and this is the first error to be reported. - */ - - retcode = -status; - ret = ERROR; - } - } -#endif - /* Case 3: mode == LIO_NOWAIT and sig == NULL * * Just return now. diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c index dccef88f7ca..af43976b159 100644 --- a/sched/mqueue/mq_sndinternal.c +++ b/sched/mqueue/mq_sndinternal.c @@ -56,9 +56,6 @@ #include #include "sched/sched.h" -#ifndef CONFIG_DISABLE_SIGNALS -# include "signal/signal.h" -#endif #include "mqueue/mqueue.h" /**************************************************************************** @@ -410,30 +407,9 @@ int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg, msgq->ntpid = INVALID_PROCESS_ID; msgq->ntmqdes = NULL; - /* Notification the client via signal? */ - - if (event.sigev_notify == SIGEV_SIGNAL) - { - /* Yes... Queue the signal -- What if this returns an error? */ - -#ifdef CONFIG_CAN_PASS_STRUCTS - DEBUGVERIFY(nxsig_mqnotempty(pid, event.sigev_signo, - event.sigev_value)); -#else - DEBUGVERIFY(nxsig_mqnotempty(pid, event.sigev_signo, - event.sigev_value.sival_ptr)); -#endif - } - -#ifdef CONFIG_SIG_EVTHREAD - /* Notify the client via a function call */ - - else if (event.sigev_notify == SIGEV_THREAD) - { - DEBUGVERIFY(nxsig_evthread(pid, &event)); - } -#endif + /* Notification the client */ + DEBUGVERIFY(nxsig_notification(pid, &event, SI_MESGQ)); } #endif diff --git a/sched/signal/Make.defs b/sched/signal/Make.defs index ae2a94ab9f4..8028be5e013 100644 --- a/sched/signal/Make.defs +++ b/sched/signal/Make.defs @@ -41,7 +41,7 @@ CSRCS += sig_kill.c sig_queue.c sig_waitinfo.c sig_timedwait.c CSRCS += sig_findaction.c sig_allocpendingsigaction.c CSRCS += sig_releasependingsigaction.c sig_unmaskpendingsignal.c CSRCS += sig_removependingsignal.c sig_releasependingsignal.c sig_lowest.c -CSRCS += sig_mqnotempty.c sig_cleanup.c sig_dispatch.c sig_deliver.c +CSRCS += sig_notification.c sig_cleanup.c sig_dispatch.c sig_deliver.c CSRCS += sig_pause.c sig_nanosleep.c sig_usleep.c sig_sleep.c ifeq ($(CONFIG_SIG_DEFAULT),y) diff --git a/sched/signal/sig_mqnotempty.c b/sched/signal/sig_notification.c similarity index 59% rename from sched/signal/sig_mqnotempty.c rename to sched/signal/sig_notification.c index c7db80b8de3..56b2b0142eb 100644 --- a/sched/signal/sig_mqnotempty.c +++ b/sched/signal/sig_notification.c @@ -1,9 +1,8 @@ /**************************************************************************** - * sched/signal/sig_mqnotempty.c + * sched/signal/sig_notification.c * - * Copyright (C) 2007-2009, 2013, 2015, 2017 Gregory Nutt. All rights - * reserved. - * Author: Gregory Nutt + * Copyright (C) 2018 Pinecone Inc. All rights reserved. + * Author: Xiang Xiao * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,14 +38,9 @@ ****************************************************************************/ #include -#include -#include -#include -#include #include - -#include +#include #include "sched/sched.h" #include "signal/signal.h" @@ -56,62 +50,64 @@ ****************************************************************************/ /**************************************************************************** - * Name: nxsig_mqnotempty + * Name: nxsig_notification * * Description: - * This function is equivalent to nxsig_queue(), but supports the - * messaging system's requirement to signal a task when a message queue - * becomes non-empty. It is identical to nxsig_queue(), except that it - * sets the si_code field in the siginfo structure to SI_MESGQ rather than - * SI_QUEUE. + * Notify a client an event via either a singal or function call + * base on the sigev_notify field. + * + * Input Parameters: + * pid - The task/thread ID a the client thread to be signaled. + * event - The instance of struct sigevent that describes how to signal + * the client. + * code - Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. * ****************************************************************************/ -#ifdef CONFIG_CAN_PASS_STRUCTS -int nxsig_mqnotempty(int pid, int signo, union sigval value) -#else -int nxsig_mqnotempty(int pid, int signo, void *sival_ptr) -#endif +int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code) { -#ifdef CONFIG_SCHED_HAVE_PARENT - FAR struct tcb_s *rtcb = this_task(); -#endif - siginfo_t info; - int ret; + sinfo("pid=%p signo=%d code=%d sival_ptr=%p\n", + pid, event->sigev_signo, code, event->value.sival_ptr); -#ifdef CONFIG_CAN_PASS_STRUCTS - sinfo("pid=%p signo=%d value=%d\n", pid, signo, value.sival_int); -#else - sinfo("pid=%p signo=%d sival_ptr=%p\n", pid, signo, sival_ptr); -#endif + /* Notify client via a signal? */ - /* Verify that we can perform the signalling operation */ - - if (!GOOD_SIGNO(signo)) + if (event->sigev_notify == SIGEV_SIGNAL) { - return -EINVAL; +#ifdef CONFIG_SCHED_HAVE_PARENT + FAR struct tcb_s *rtcb = this_task(); +#endif + siginfo_t info; + + /* Yes.. Create the siginfo structure */ + + info.si_signo = event->sigev_signo; + info.si_code = code; + info.si_errno = OK; + info.si_value = event->sigev_value; +#ifdef CONFIG_SCHED_HAVE_PARENT + info.si_pid = rtcb->pid; + info.si_status = OK; +#endif + + /* Send the signal */ + + return nxsig_dispatch(pid, &info); } - /* Create the siginfo structure */ +#ifdef CONFIG_SIG_EVTHREAD + /* Notify the client via a function call */ - info.si_signo = signo; - info.si_code = SI_MESGQ; - info.si_errno = OK; -#ifdef CONFIG_CAN_PASS_STRUCTS - info.si_value = value; -#else - info.si_value.sival_ptr = sival_ptr; -#endif -#ifdef CONFIG_SCHED_HAVE_PARENT - info.si_pid = rtcb->pid; - info.si_status = OK; + else if (event->sigev_notify == SIGEV_THREAD) + { + return nxsig_evthread(pid, event); + } #endif - /* Process the receipt of the signal */ - - sched_lock(); - ret = nxsig_dispatch(pid, &info); - sched_unlock(); - - return ret; + return event->sigev_notify == SIGEV_NONE ? OK : -ENOSYS; } + diff --git a/sched/signal/signal.h b/sched/signal/signal.h index 32d72a6c38e..56289efad81 100644 --- a/sched/signal/signal.h +++ b/sched/signal/signal.h @@ -207,10 +207,8 @@ FAR sigq_t *nxsig_alloc_pendingsigaction(void); void nxsig_deliver(FAR struct tcb_s *stcb); FAR sigactq_t *nxsig_find_action(FAR struct task_group_s *group, int signo); int nxsig_lowest(FAR sigset_t *set); -#ifdef CONFIG_CAN_PASS_STRUCTS -int nxsig_mqnotempty(int tid, int signo, union sigval value); -#else -int nxsig_mqnotempty(int tid, int signo, FAR void *sival_ptr); +#if defined(CONFIG_SIG_EVTHREAD) && defined(CONFIG_BUILD_FLAT) +int nxsig_evthread(pid_t pid, FAR struct sigevent *event); #endif void nxsig_release_pendingsigaction(FAR sigq_t *sigq); void nxsig_release_pendingsignal(FAR sigpendq_t *sigpend); diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c index 0f6741d6fc9..99aa89029ed 100644 --- a/sched/timer/timer_settime.c +++ b/sched/timer/timer_settime.c @@ -49,7 +49,6 @@ #include #include "clock/clock.h" -#include "signal/signal.h" #include "timer/timer.h" #ifndef CONFIG_DISABLE_POSIX_TIMERS @@ -87,40 +86,7 @@ static void timer_timeout(int argc, wdparm_t itimer); static inline void timer_signotify(FAR struct posix_timer_s *timer) { - siginfo_t info; - - /* Notify client via a signal? */ - - if (timer->pt_event.sigev_notify == SIGEV_SIGNAL) - { - /* Yes.. Create the siginfo structure */ - - info.si_signo = timer->pt_event.sigev_signo; - info.si_code = SI_TIMER; - info.si_errno = OK; -#ifdef CONFIG_CAN_PASS_STRUCTS - info.si_value = timer->pt_event.sigev_value; -#else - info.si_value.sival_ptr = timer->pt_event.sigev_value.sival_ptr; -#endif -#ifdef CONFIG_SCHED_HAVE_PARENT - info.si_pid = 0; /* Not applicable */ - info.si_status = OK; -#endif - - /* Send the signal */ - - DEBUGVERIFY(nxsig_dispatch(timer->pt_owner, &info)); - } - -#ifdef CONFIG_SIG_EVTHREAD - /* Notify the client via a function call */ - - else if (timer->pt_event.sigev_notify == SIGEV_THREAD) - { - DEBUGVERIFY(nxsig_evthread(timer->pt_owner, &timer->pt_event)); - } -#endif + DEBUGVERIFY(nxsig_notification(timer->pt_owner, &timer->pt_event, SI_TIMER)); } /****************************************************************************