sched/signal and related changes to other OS subsystems.

This commit is contained in:
Xiang Xiao
2019-01-27 09:28:59 -06:00
committed by Gregory Nutt
parent d105dc9b5e
commit fb63c0a293
34 changed files with 212 additions and 225 deletions
+6 -1
View File
@@ -105,6 +105,7 @@ struct ajoy_open_s
pid_t ao_pid; pid_t ao_pid;
struct ajoy_notify_s ao_notify; struct ajoy_notify_s ao_notify;
struct sigwork_s ao_work;
#endif #endif
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
@@ -376,7 +377,7 @@ static void ajoy_sample(FAR struct ajoy_upperhalf_s *priv)
opriv->ao_notify.an_event.sigev_value.sival_int = sample; opriv->ao_notify.an_event.sigev_value.sival_int = sample;
nxsig_notification(opriv->ao_pid, &opriv->ao_notify.an_event, nxsig_notification(opriv->ao_pid, &opriv->ao_notify.an_event,
SI_QUEUE); SI_QUEUE, &opriv->ao_work);
} }
#endif #endif
} }
@@ -532,6 +533,10 @@ static int ajoy_close(FAR struct file *filep)
priv->au_open = opriv->ao_flink; priv->au_open = opriv->ao_flink;
} }
/* Cancel any pending notification */
nxsig_cancel_notification(&opriv->ao_work);
/* And free the open structure */ /* And free the open structure */
kmm_free(opriv); kmm_free(opriv);
+7 -2
View File
@@ -101,6 +101,7 @@ struct btn_open_s
pid_t bo_pid; pid_t bo_pid;
struct btn_notify_s bo_notify; struct btn_notify_s bo_notify;
struct sigwork_s bo_work;
#endif #endif
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
@@ -358,8 +359,8 @@ static void btn_sample(FAR struct btn_upperhalf_s *priv)
opriv->bo_notify.bn_event.sigev_value.sival_int = sample; opriv->bo_notify.bn_event.sigev_value.sival_int = sample;
nxsig_notification(opriv->bo_pid, &opriv->bo_notify.bn_event, nxsig_notification(opriv->bo_pid, &opriv->bo_notify.bn_event,
SI_QUEUE); SI_QUEUE, &opriv->bo_work);
} }
#endif #endif
} }
@@ -518,6 +519,10 @@ static int btn_close(FAR struct file *filep)
priv->bu_open = opriv->bo_flink; priv->bu_open = opriv->bo_flink;
} }
/* Cancel any pending notification */
nxsig_cancel_notification(&opriv->bo_work);
/* And free the open structure */ /* And free the open structure */
kmm_free(opriv); kmm_free(opriv);
+6 -1
View File
@@ -105,6 +105,7 @@ struct djoy_open_s
pid_t do_pid; pid_t do_pid;
struct djoy_notify_s do_notify; struct djoy_notify_s do_notify;
struct sigwork_s do_work;
#endif #endif
#ifndef CONFIG_DISABLE_POLL #ifndef CONFIG_DISABLE_POLL
@@ -376,7 +377,7 @@ static void djoy_sample(FAR struct djoy_upperhalf_s *priv)
opriv->do_notify.dn_event.sigev_value.sival_int = sample; opriv->do_notify.dn_event.sigev_value.sival_int = sample;
nxsig_notification(opriv->do_pid, &opriv->do_notify.dn_event, nxsig_notification(opriv->do_pid, &opriv->do_notify.dn_event,
SI_QUEUE); SI_QUEUE, &opriv->do_work);
} }
#endif #endif
} }
@@ -532,6 +533,10 @@ static int djoy_close(FAR struct file *filep)
priv->du_open = opriv->do_flink; priv->du_open = opriv->do_flink;
} }
/* Cancel any pending notification */
nxsig_cancel_notification(&opriv->do_work);
/* And free the open structure */ /* And free the open structure */
kmm_free(opriv); kmm_free(opriv);
+3 -2
View File
@@ -46,7 +46,6 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <nuttx/signal.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/ioexpander/gpio.h> #include <nuttx/ioexpander/gpio.h>
@@ -113,7 +112,8 @@ static int gpio_handler(FAR struct gpio_dev_s *dev, uint8_t pin)
break; break;
} }
nxsig_notification(signal->gp_pid, &signal->gp_event, SI_QUEUE); nxsig_notification(signal->gp_pid, &signal->gp_event,
SI_QUEUE, &signal->gp_work);
} }
return OK; return OK;
@@ -329,6 +329,7 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
} }
dev->gp_signals[j].gp_pid = 0; dev->gp_signals[j].gp_pid = 0;
nxsig_cancel_notification(&dev->gp_signals[j].gp_work);
ret = OK; ret = OK;
break; break;
} }
+5 -2
View File
@@ -58,7 +58,6 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/semaphore.h> #include <nuttx/semaphore.h>
#include <nuttx/signal.h>
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
@@ -276,7 +275,7 @@ static void ft80x_notify(FAR struct ft80x_dev_s *priv,
/* Yes.. Signal the client */ /* Yes.. Signal the client */
info->event.sigev_value.sival_int = value; info->event.sigev_value.sival_int = value;
nxsig_notification(info->pid, &info->event, SI_QUEUE); nxsig_notification(info->pid, &info->event, SI_QUEUE, &info->work);
} }
} }
@@ -1055,6 +1054,10 @@ static int ft80x_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
regval = ft80x_read_word(priv, FT80X_REG_INT_MASK); regval = ft80x_read_word(priv, FT80X_REG_INT_MASK);
regval &= ~(1 << notify->id); regval &= ~(1 << notify->id);
ft80x_write_word(priv, FT80X_REG_INT_MASK, regval); ft80x_write_word(priv, FT80X_REG_INT_MASK, regval);
/* Cancel any pending notification */
nxsig_cancel_notification(&info->work);
ret = OK; ret = OK;
} }
} }
+2 -2
View File
@@ -49,10 +49,9 @@
*******************************************************************************************/ *******************************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/signal.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <signal.h>
/******************************************************************************************* /*******************************************************************************************
* Public Types * Public Types
*******************************************************************************************/ *******************************************************************************************/
@@ -160,6 +159,7 @@ struct ft80x_i2cwrite_s
struct ft80x_eventinfo_s struct ft80x_eventinfo_s
{ {
struct sigevent event; /* Describe the way a task is to be notified */ struct sigevent event; /* Describe the way a task is to be notified */
struct sigwork_s work; /* Work for SIGEV_THREAD */
bool enable; /* True: enable notification; false: disable */ bool enable; /* True: enable notification; false: disable */
int16_t pid; /* Send the notification to this task */ int16_t pid; /* Send the notification to this task */
}; };
+7 -1
View File
@@ -104,6 +104,7 @@ struct phy_notify_s
char intf[CONFIG_PHY_NOTIFICATION_MAXINTFLEN+1]; char intf[CONFIG_PHY_NOTIFICATION_MAXINTFLEN+1];
pid_t pid; pid_t pid;
struct sigevent event; struct sigevent event;
struct sigwork_s work;
phy_enable_t enable; phy_enable_t enable;
}; };
@@ -243,7 +244,8 @@ static int phy_handler(int irq, FAR void *context, FAR void *arg)
/* Signal the client that the PHY has something interesting to say to us */ /* Signal the client that the PHY has something interesting to say to us */
ret = nxsig_notification(client->pid, &client->event, SI_QUEUE); ret = nxsig_notification(client->pid, &client->event,
SI_QUEUE, &client->work);
if (ret < 0) if (ret < 0)
{ {
phyerr("ERROR: nxsig_notification failed: %d\n", ret); phyerr("ERROR: nxsig_notification failed: %d\n", ret);
@@ -380,6 +382,10 @@ int phy_notify_unsubscribe(FAR const char *intf, pid_t pid)
phy_semtake(); phy_semtake();
(void)arch_phy_irq(intf, NULL, NULL, NULL); (void)arch_phy_irq(intf, NULL, NULL, NULL);
/* Cancel any pending notification */
nxsig_cancel_notification(&client->work);
/* Un-initialize the client entry */ /* Un-initialize the client entry */
client->assigned = false; client->assigned = false;
+7 -1
View File
@@ -104,6 +104,7 @@ struct zc_open_s
pid_t do_pid; pid_t do_pid;
struct sigevent do_event; struct sigevent do_event;
struct sigwork_s do_work;
}; };
/**************************************************************************** /****************************************************************************
@@ -205,7 +206,8 @@ static void zerocross_interrupt(FAR const struct zc_lowerhalf_s *lower,
/* Signal the waiter */ /* Signal the waiter */
opriv->do_event.sigev_value.sival_int = sample; opriv->do_event.sigev_value.sival_int = sample;
nxsig_notification(opriv->do_pid, &opriv->do_event, SI_QUEUE); nxsig_notification(opriv->do_pid, &opriv->do_event,
SI_QUEUE, &opriv->do_work);
} }
leave_critical_section(flags); leave_critical_section(flags);
@@ -346,6 +348,10 @@ static int zc_close(FAR struct file *filep)
priv->zu_open = opriv->do_flink; priv->zu_open = opriv->do_flink;
} }
/* Cancel any pending notification */
nxsig_cancel_notification(&opriv->do_work);
/* And free the open structure */ /* And free the open structure */
kmm_free(opriv); kmm_free(opriv);
+4 -1
View File
@@ -76,6 +76,7 @@ struct oneshot_dev_s
/* Oneshot timer expiration notification information */ /* Oneshot timer expiration notification information */
struct sigevent od_event; /* Signal info */ struct sigevent od_event; /* Signal info */
struct sigwork_s od_work; /* Signal work */
pid_t od_pid; /* PID to be notified */ pid_t od_pid; /* PID to be notified */
}; };
@@ -132,7 +133,8 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
/* Signal the waiter.. if there is one */ /* Signal the waiter.. if there is one */
nxsig_notification(priv->od_pid, &priv->od_event, SI_QUEUE); nxsig_notification(priv->od_pid, &priv->od_event,
SI_QUEUE, &priv->od_work);
} }
/**************************************************************************** /****************************************************************************
@@ -292,6 +294,7 @@ static int oneshot_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
/* Cancel the oneshot timer */ /* Cancel the oneshot timer */
ret = ONESHOT_CANCEL(priv->od_lower, ts); ret = ONESHOT_CANCEL(priv->od_lower, ts);
nxsig_cancel_notification(&priv->od_work);
} }
break; break;
+7 -2
View File
@@ -60,6 +60,7 @@ struct rtc_alarminfo_s
bool active; /* True: alarm is active */ bool active; /* True: alarm is active */
pid_t pid; /* Identifies task to be notified */ pid_t pid; /* Identifies task to be notified */
struct sigevent event; /* Describe the way a task is to be notified */ struct sigevent event; /* Describe the way a task is to be notified */
struct sigwork_s work; /* Signal work */
}; };
#endif #endif
@@ -196,7 +197,8 @@ static void rtc_alarm_callback(FAR void *priv, int alarmid)
{ {
/* Yes.. signal the alarm expiration */ /* Yes.. signal the alarm expiration */
nxsig_notification(alarminfo->pid, &alarminfo->event, SI_QUEUE); nxsig_notification(alarminfo->pid, &alarminfo->event,
SI_QUEUE, &alarminfo->work);
} }
/* The alarm is no longer active */ /* The alarm is no longer active */
@@ -227,7 +229,8 @@ static void rtc_periodic_callback(FAR void *priv, int alarmid)
{ {
/* Yes.. signal the alarm expiration */ /* Yes.. signal the alarm expiration */
nxsig_notification(alarminfo->pid, &alarminfo->event, SI_QUEUE); nxsig_notification(alarminfo->pid, &alarminfo->event,
SI_QUEUE, &alarminfo->work);
} }
/* The alarm is no longer active */ /* The alarm is no longer active */
@@ -566,6 +569,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (ret == OK) if (ret == OK)
{ {
upperinfo->active = false; upperinfo->active = false;
nxsig_cancel_notification(&upperinfo->work);
} }
} }
} }
@@ -698,6 +702,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
if (ret == OK) if (ret == OK)
{ {
upperinfo->active = false; upperinfo->active = false;
nxsig_cancel_notification(&upperinfo->work);
} }
} }
} }
@@ -165,6 +165,7 @@ struct xbeenet_driver_s
bool xd_notify_registered; bool xd_notify_registered;
pid_t xd_notify_pid; pid_t xd_notify_pid;
struct sigevent xd_notify_event; struct sigevent xd_notify_event;
struct sigwork_s xd_notify_work;
#endif #endif
}; };
@@ -446,7 +447,7 @@ static int xbeenet_notify(FAR struct xbee_maccb_s *maccb,
{ {
priv->xd_notify_event.sigev_value.sival_int = primitive->type; priv->xd_notify_event.sigev_value.sival_int = primitive->type;
nxsig_notification(priv->xd_notify_pid, &priv->xd_notify_event, nxsig_notification(priv->xd_notify_pid, &priv->xd_notify_event,
SI_QUEUE); SI_QUEUE, &priv->xd_notify_work);
} }
#endif #endif
+1
View File
@@ -210,6 +210,7 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp)
/* The result -EINPROGRESS means that the transfer has not yet completed */ /* The result -EINPROGRESS means that the transfer has not yet completed */
sigwork_init(&aiocbp->aio_sigwork);
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
+1
View File
@@ -259,6 +259,7 @@ int aio_read(FAR struct aiocb *aiocbp)
/* The result -EINPROGRESS means that the transfer has not yet completed */ /* The result -EINPROGRESS means that the transfer has not yet completed */
sigwork_init(&aiocbp->aio_sigwork);
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
+2 -1
View File
@@ -91,7 +91,8 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp)
/* Signal the client */ /* Signal the client */
ret = nxsig_notification(pid, &aiocbp->aio_sigevent, SI_ASYNCIO); ret = nxsig_notification(pid, &aiocbp->aio_sigevent,
SI_ASYNCIO, &aiocbp->aio_sigwork);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: nxsig_notification failed: %d\n", ret); ferr("ERROR: nxsig_notification failed: %d\n", ret);
+1
View File
@@ -309,6 +309,7 @@ int aio_write(FAR struct aiocb *aiocbp)
/* The result -EINPROGRESS means that the transfer has not yet completed */ /* The result -EINPROGRESS means that the transfer has not yet completed */
sigwork_init(&aiocbp->aio_sigwork);
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
+2 -1
View File
@@ -43,9 +43,9 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h>
#include <time.h> #include <time.h>
#include <nuttx/signal.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
/**************************************************************************** /****************************************************************************
@@ -137,6 +137,7 @@ struct aiocb
* application code should never reference these elements. * application code should never reference these elements.
*/ */
struct sigwork_s aio_sigwork; /* Signal work */
volatile ssize_t aio_result; /* Support for aio_error() and aio_return() */ volatile ssize_t aio_result; /* Support for aio_error() and aio_return() */
FAR void *aio_priv; /* Used by signal handlers */ FAR void *aio_priv; /* Used by signal handlers */
}; };
+2 -1
View File
@@ -45,8 +45,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <signal.h>
#include <nuttx/signal.h>
#include <nuttx/fs/ioctl.h> #include <nuttx/fs/ioctl.h>
/**************************************************************************** /****************************************************************************
@@ -144,6 +144,7 @@ struct gpio_operations_s
struct gpio_signal_s struct gpio_signal_s
{ {
struct sigevent gp_event; struct sigevent gp_event;
struct sigwork_s gp_work;
pid_t gp_pid; /* The task to be signaled */ pid_t gp_pid; /* The task to be signaled */
}; };
+2 -1
View File
@@ -43,13 +43,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/compiler.h> #include <nuttx/compiler.h>
#include <nuttx/signal.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <mqueue.h> #include <mqueue.h>
#include <queue.h> #include <queue.h>
#include <signal.h>
#if CONFIG_MQ_MAXMSGSIZE > 0 #if CONFIG_MQ_MAXMSGSIZE > 0
@@ -117,6 +117,7 @@ struct mqueue_inode_s
FAR struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */ FAR struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */
pid_t ntpid; /* Notification: Receiving Task's PID */ pid_t ntpid; /* Notification: Receiving Task's PID */
struct sigevent ntevent; /* Notification description */ struct sigevent ntevent; /* Notification description */
struct sigwork_s ntwork; /* Notification work */
#endif #endif
}; };
+47 -1
View File
@@ -41,11 +41,35 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/wqueue.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdbool.h> #include <stdbool.h>
#include <signal.h> #include <signal.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_SIG_EVTHREAD
#define sigwork_init(work) memset(work, 0, sizeof(*work));
#else
#define sigwork_init(work) (void)(work)
#endif
/****************************************************************************
* Public Type Definitions
****************************************************************************/
struct sigwork_s
{
#ifdef CONFIG_SIG_EVTHREAD
struct work_s work; /* Work queue structure */
union sigval value; /* Data passed with notification */
sigev_notify_function_t func; /* Notification function */
#endif
};
/**************************************************************************** /****************************************************************************
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
@@ -445,6 +469,7 @@ int nxsig_usleep(useconds_t usec);
* event - The instance of struct sigevent that describes how to signal * event - The instance of struct sigevent that describes how to signal
* the client. * the client.
* code - Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ * code - Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ
* work - The work structure to queue
* *
* Returned Value: * Returned Value:
* This is an internal OS interface and should not be used by applications. * This is an internal OS interface and should not be used by applications.
@@ -453,6 +478,27 @@ int nxsig_usleep(useconds_t usec);
* *
****************************************************************************/ ****************************************************************************/
int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code); int nxsig_notification(pid_t pid, FAR struct sigevent *event,
int code, FAR struct sigwork_s *work);
/****************************************************************************
* Name: nxsig_cancel_notification
*
* Description:
* Cancel the notification if it doesn't send yet.
*
* Input Parameters:
* work - The work structure to cancel
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_SIG_EVTHREAD
void nxsig_cancel_notification(FAR struct sigwork_s *work);
#else
#define nxsig_cancel_notification(work) (void)(work)
#endif
#endif /* __INCLUDE_NUTTX_SIGNAL_H */ #endif /* __INCLUDE_NUTTX_SIGNAL_H */
+3 -2
View File
@@ -192,7 +192,7 @@ static void lio_sighandler(int signo, siginfo_t *info, void *ucontext)
/* Signal the client */ /* Signal the client */
DEBUGVERIFY(nxsig_notification(sighand->pid, &sighand->sig, DEBUGVERIFY(nxsig_notification(sighand->pid, &sighand->sig,
SI_ASYNCIO)); SI_ASYNCIO, &aiocbp->aio_sigwork));
/* And free the container */ /* And free the container */
@@ -676,7 +676,8 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent,
} }
else else
{ {
status = nxsig_notification(getpid(), sig, SI_ASYNCIO); status = nxsig_notification(getpid(), sig,
SI_ASYNCIO, &aiocbp->aio_sigwork);
if (status < 0 && ret == OK) if (status < 0 && ret == OK)
{ {
/* Something bad happened while performing the notification /* Something bad happened while performing the notification
+1
View File
@@ -116,6 +116,7 @@ void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
memset(&msgq->ntevent, 0, sizeof(struct sigevent)); memset(&msgq->ntevent, 0, sizeof(struct sigevent));
msgq->ntpid = INVALID_PROCESS_ID; msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntmqdes = NULL; msgq->ntmqdes = NULL;
nxsig_cancel_notification(&msgq->ntwork);
} }
#endif #endif
-2
View File
@@ -53,8 +53,6 @@
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/mqueue.h> #include <nuttx/mqueue.h>
#include "signal/signal.h"
#include "mqueue/mqueue.h" #include "mqueue/mqueue.h"
/**************************************************************************** /****************************************************************************
+1 -1
View File
@@ -39,7 +39,6 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <signal.h>
#include <mqueue.h> #include <mqueue.h>
#include <sched.h> #include <sched.h>
#include <string.h> #include <string.h>
@@ -182,6 +181,7 @@ int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)
memset(&msgq->ntevent, 0, sizeof(struct sigevent)); memset(&msgq->ntevent, 0, sizeof(struct sigevent));
msgq->ntpid = INVALID_PROCESS_ID; msgq->ntpid = INVALID_PROCESS_ID;
msgq->ntmqdes = NULL; msgq->ntmqdes = NULL;
nxsig_cancel_notification(&msgq->ntwork);
} }
sched_unlock(); sched_unlock();
+2 -2
View File
@@ -52,7 +52,6 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/signal.h>
#include <nuttx/cancelpt.h> #include <nuttx/cancelpt.h>
#include "sched/sched.h" #include "sched/sched.h"
@@ -414,7 +413,8 @@ int nxmq_do_send(mqd_t mqdes, FAR struct mqueue_msg_s *mqmsg,
/* Notification the client */ /* Notification the client */
DEBUGVERIFY(nxsig_notification(pid, &event, SI_MESGQ)); DEBUGVERIFY(nxsig_notification(pid, &event,
SI_MESGQ, &msgq->ntwork));
} }
#endif #endif
-1
View File
@@ -49,7 +49,6 @@
#include <limits.h> #include <limits.h>
#include <mqueue.h> #include <mqueue.h>
#include <sched.h> #include <sched.h>
#include <signal.h>
#include <nuttx/mqueue.h> #include <nuttx/mqueue.h>
-4
View File
@@ -48,10 +48,6 @@ ifeq ($(CONFIG_SIG_DEFAULT),y)
CSRCS += sig_default.c CSRCS += sig_default.c
endif endif
ifeq ($(CONFIG_SIG_EVTHREAD),y)
CSRCS += sig_evthread.c
endif
ifneq ($(CONFIG_DISABLE_POLL),y) ifneq ($(CONFIG_DISABLE_POLL),y)
CSRCS += sig_ppoll.c sig_pselect.c CSRCS += sig_ppoll.c sig_pselect.c
endif endif
-175
View File
@@ -1,175 +0,0 @@
/****************************************************************************
* sched/signal/sig_evthread.c
*
* Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <signal.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#ifdef CONFIG_SIG_EVTHREAD
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Use the low-prioriry work queue is it is available */
#if defined(CONFIG_SCHED_LPWORK)
# define NTWORK LPWORK
#elif defined(CONFIG_SCHED_HPWORK)
# define NTWORK HPWORK
#else
# error Work queue is not enabled
#endif
/****************************************************************************
* Private Type Definitions
****************************************************************************/
/* This structure retains all that is necessary to perform the notification */
struct sig_evthread_s
{
struct work_s nt_work; /* Work queue structure */
union sigval nt_value; /* Data passed with notification */
sigev_notify_function_t nt_func; /* Notification function */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxsig_evthread_worker
*
* Description:
* Perform the callback from the context of the worker thread.
*
* Input Parameters:
* arg - Work argument.
*
* Returned Value:
* None.
*
****************************************************************************/
static void nxsig_evthread_worker(FAR void *arg)
{
FAR struct sig_evthread_s *notify = (FAR struct sig_evthread_s *)arg;
DEBUGASSERT(notify != NULL);
/* Perform the callback */
#ifdef CONFIG_CAN_PASS_STRUCTS
notify->nt_func(notify->nt_value);
#else
notify->nt_func(notify->nt_value.sival_ptr);
#endif
/* Free the alloated notification parameters */
kmm_free(notify);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxsig_evthread
*
* Description:
* Notify a client a signal event via a function call. This function is
* an internal OS interface that implements the common logic for signal
* event notification for the case of SIGEV_THREAD.
*
* 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.
*
* 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.
*
****************************************************************************/
int nxsig_evthread(pid_t pid, FAR struct sigevent *event)
{
FAR struct sig_evthread_s *notify;
DEBUGASSERT(event != NULL && event->sigev_notify_function != NULL);
int ret;
/* Allocate a structure to hold the notification information */
notify = kmm_zalloc(sizeof(struct sig_evthread_s));
if (notify == NULL)
{
return -ENOMEM;
}
/* Initialize the notification information */
#ifdef CONFIG_CAN_PASS_STRUCTS
notify->nt_value = event->sigev_value;
#else
notify->nt_value.sival_ptr = event->sigev_value.sival_ptr;
#endif
notify->nt_func = event->sigev_notify_function;
/* Then queue the work */
ret = work_queue(NTWORK, &notify->nt_work, nxsig_evthread_worker,
notify, 0);
if (ret < 0)
{
kmm_free(notify);
}
return ret;
}
#endif /* CONFIG_SIG_EVTHREAD */
+68 -2
View File
@@ -50,6 +50,38 @@
#include "sched/sched.h" #include "sched/sched.h"
#include "signal/signal.h" #include "signal/signal.h"
/****************************************************************************
* Name: nxsig_notification_worker
*
* Description:
* Perform the callback from the context of the worker thread.
*
* Input Parameters:
* arg - Work argument.
*
* Returned Value:
* None.
*
****************************************************************************/
#ifdef CONFIG_SIG_EVTHREAD
static void nxsig_notification_worker(FAR void *arg)
{
FAR struct sigwork_s *work = (FAR struct sigwork_s *)arg;
DEBUGASSERT(work != NULL);
/* Perform the callback */
#ifdef CONFIG_CAN_PASS_STRUCTS
work->func(work->value);
#else
work->func(work->value.sival_ptr);
#endif
}
#endif /* CONFIG_SIG_EVTHREAD */
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -66,6 +98,7 @@
* event - The instance of struct sigevent that describes how to signal * event - The instance of struct sigevent that describes how to signal
* the client. * the client.
* code - Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ * code - Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ
* work - The work structure to queue
* *
* Returned Value: * Returned Value:
* This is an internal OS interface and should not be used by applications. * This is an internal OS interface and should not be used by applications.
@@ -74,7 +107,8 @@
* *
****************************************************************************/ ****************************************************************************/
int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code) int nxsig_notification(pid_t pid, FAR struct sigevent *event,
int code, FAR struct sigwork_s *work)
{ {
sinfo("pid=%p signo=%d code=%d sival_ptr=%p\n", sinfo("pid=%p signo=%d code=%d sival_ptr=%p\n",
pid, event->sigev_signo, code, event->sigev_value.sival_ptr); pid, event->sigev_signo, code, event->sigev_value.sival_ptr);
@@ -109,10 +143,42 @@ int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code)
else if (event->sigev_notify == SIGEV_THREAD) else if (event->sigev_notify == SIGEV_THREAD)
{ {
return nxsig_evthread(pid, event); /* Initialize the work information */
#ifdef CONFIG_CAN_PASS_STRUCTS
work->value = event->sigev_value;
#else
work->value.sival_ptr = event->sigev_value.sival_ptr;
#endif
work->func = event->sigev_notify_function;
/* Then queue the work */
return work_queue(LPWORK, &work->work,
nxsig_notification_worker, work, 0);
} }
#endif #endif
return event->sigev_notify == SIGEV_NONE ? OK : -ENOSYS; return event->sigev_notify == SIGEV_NONE ? OK : -ENOSYS;
} }
/****************************************************************************
* Name: nxsig_cancel_notification
*
* Description:
* Cancel the notification if it doesn't send yet.
*
* Input Parameters:
* work - The work structure to cancel
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_SIG_EVTHREAD
void nxsig_cancel_notification(FAR struct sigwork_s *work)
{
work_cancel(LPWORK, &work->work);
}
#endif
-3
View File
@@ -207,9 +207,6 @@ FAR sigq_t *nxsig_alloc_pendingsigaction(void);
void nxsig_deliver(FAR struct tcb_s *stcb); void nxsig_deliver(FAR struct tcb_s *stcb);
FAR sigactq_t *nxsig_find_action(FAR struct task_group_s *group, int signo); FAR sigactq_t *nxsig_find_action(FAR struct task_group_s *group, int signo);
int nxsig_lowest(FAR sigset_t *set); int nxsig_lowest(FAR sigset_t *set);
#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_pendingsigaction(FAR sigq_t *sigq);
void nxsig_release_pendingsignal(FAR sigpendq_t *sigpend); void nxsig_release_pendingsignal(FAR sigpendq_t *sigpend);
FAR sigpendq_t *nxsig_remove_pendingsignal(FAR struct tcb_s *stcb, int signo); FAR sigpendq_t *nxsig_remove_pendingsignal(FAR struct tcb_s *stcb, int signo);
+9 -8
View File
@@ -44,9 +44,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <signal.h>
#include <nuttx/compiler.h> #include <nuttx/compiler.h>
#include <nuttx/signal.h>
#include <nuttx/wdog.h> #include <nuttx/wdog.h>
/**************************************************************************** /****************************************************************************
@@ -65,13 +65,14 @@ struct posix_timer_s
{ {
FAR struct posix_timer_s *flink; FAR struct posix_timer_s *flink;
uint8_t pt_flags; /* See PT_FLAGS_* definitions */ uint8_t pt_flags; /* See PT_FLAGS_* definitions */
uint8_t pt_crefs; /* Reference count */ uint8_t pt_crefs; /* Reference count */
pid_t pt_owner; /* Creator of timer */ pid_t pt_owner; /* Creator of timer */
int pt_delay; /* If non-zero, used to reset repetitive timers */ int pt_delay; /* If non-zero, used to reset repetitive timers */
int pt_last; /* Last value used to set watchdog */ int pt_last; /* Last value used to set watchdog */
WDOG_ID pt_wdog; /* The watchdog that provides the timing */ WDOG_ID pt_wdog; /* The watchdog that provides the timing */
struct sigevent pt_event; /* Notification information */ struct sigevent pt_event; /* Notification information */
struct sigwork_s pt_work;
}; };
/**************************************************************************** /****************************************************************************
+4
View File
@@ -140,6 +140,10 @@ int timer_release(FAR struct posix_timer_s *timer)
(void)wd_delete(timer->pt_wdog); (void)wd_delete(timer->pt_wdog);
/* Cancel any pending notification */
nxsig_cancel_notification(&timer->pt_work);
/* Release the timer structure */ /* Release the timer structure */
timer_free(timer); timer_free(timer);
+6 -2
View File
@@ -46,7 +46,6 @@
#include <errno.h> #include <errno.h>
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/signal.h>
#include "clock/clock.h" #include "clock/clock.h"
#include "timer/timer.h" #include "timer/timer.h"
@@ -86,7 +85,8 @@ static void timer_timeout(int argc, wdparm_t itimer);
static inline void timer_signotify(FAR struct posix_timer_s *timer) static inline void timer_signotify(FAR struct posix_timer_s *timer)
{ {
DEBUGVERIFY(nxsig_notification(timer->pt_owner, &timer->pt_event, SI_TIMER)); DEBUGVERIFY(nxsig_notification(timer->pt_owner, &timer->pt_event,
SI_TIMER, &timer->pt_work));
} }
/**************************************************************************** /****************************************************************************
@@ -288,6 +288,10 @@ int timer_settime(timer_t timerid, int flags,
(void)wd_cancel(timer->pt_wdog); (void)wd_cancel(timer->pt_wdog);
/* Cancel any pending notification */
nxsig_cancel_notification(&timer->pt_work);
/* If the it_value member of value is zero, the timer will not be re-armed */ /* If the it_value member of value is zero, the timer will not be re-armed */
if (value->it_value.tv_sec <= 0 && value->it_value.tv_nsec <= 0) if (value->it_value.tv_sec <= 0 && value->it_value.tv_nsec <= 0)
+2 -1
View File
@@ -122,6 +122,7 @@ struct mac802154_chardevice_s
bool md_notify_registered; bool md_notify_registered;
pid_t md_notify_pid; pid_t md_notify_pid;
struct sigevent md_notify_event; struct sigevent md_notify_event;
struct sigwork_s md_notify_work;
#endif #endif
}; };
@@ -768,7 +769,7 @@ static int mac802154dev_notify(FAR struct mac802154_maccb_s *maccb,
{ {
dev->md_notify_event.sigev_value.sival_int = primitive->type; dev->md_notify_event.sigev_value.sival_int = primitive->type;
nxsig_notification(dev->md_notify_pid, &dev->md_notify_event, nxsig_notification(dev->md_notify_pid, &dev->md_notify_event,
SI_QUEUE); SI_QUEUE, &dev->md_notify_work);
} }
#endif #endif
+2 -1
View File
@@ -165,6 +165,7 @@ struct macnet_driver_s
bool md_notify_registered; bool md_notify_registered;
pid_t md_notify_pid; pid_t md_notify_pid;
struct sigevent md_notify_event; struct sigevent md_notify_event;
struct sigwork_s md_notify_work;
#endif #endif
}; };
@@ -446,7 +447,7 @@ static int macnet_notify(FAR struct mac802154_maccb_s *maccb,
{ {
priv->md_notify_event.sigev_value.sival_int = primitive->type; priv->md_notify_event.sigev_value.sival_int = primitive->type;
nxsig_notification(priv->md_notify_pid, &priv->md_notify_event, nxsig_notification(priv->md_notify_pid, &priv->md_notify_event,
SI_QUEUE); SI_QUEUE, &priv->md_notify_work);
} }
#endif #endif