mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
sched/signal and related changes to other OS subsystems.
This commit is contained in:
@@ -105,6 +105,7 @@ struct ajoy_open_s
|
||||
|
||||
pid_t ao_pid;
|
||||
struct ajoy_notify_s ao_notify;
|
||||
struct sigwork_s ao_work;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
nxsig_notification(opriv->ao_pid, &opriv->ao_notify.an_event,
|
||||
SI_QUEUE);
|
||||
SI_QUEUE, &opriv->ao_work);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -532,6 +533,10 @@ static int ajoy_close(FAR struct file *filep)
|
||||
priv->au_open = opriv->ao_flink;
|
||||
}
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&opriv->ao_work);
|
||||
|
||||
/* And free the open structure */
|
||||
|
||||
kmm_free(opriv);
|
||||
|
||||
@@ -101,6 +101,7 @@ struct btn_open_s
|
||||
|
||||
pid_t bo_pid;
|
||||
struct btn_notify_s bo_notify;
|
||||
struct sigwork_s bo_work;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
nxsig_notification(opriv->bo_pid, &opriv->bo_notify.bn_event,
|
||||
SI_QUEUE);
|
||||
}
|
||||
SI_QUEUE, &opriv->bo_work);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -518,6 +519,10 @@ static int btn_close(FAR struct file *filep)
|
||||
priv->bu_open = opriv->bo_flink;
|
||||
}
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&opriv->bo_work);
|
||||
|
||||
/* And free the open structure */
|
||||
|
||||
kmm_free(opriv);
|
||||
|
||||
@@ -105,6 +105,7 @@ struct djoy_open_s
|
||||
|
||||
pid_t do_pid;
|
||||
struct djoy_notify_s do_notify;
|
||||
struct sigwork_s do_work;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
nxsig_notification(opriv->do_pid, &opriv->do_notify.dn_event,
|
||||
SI_QUEUE);
|
||||
SI_QUEUE, &opriv->do_work);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -532,6 +533,10 @@ static int djoy_close(FAR struct file *filep)
|
||||
priv->du_open = opriv->do_flink;
|
||||
}
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&opriv->do_work);
|
||||
|
||||
/* And free the open structure */
|
||||
|
||||
kmm_free(opriv);
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
|
||||
@@ -113,7 +112,8 @@ static int gpio_handler(FAR struct gpio_dev_s *dev, uint8_t pin)
|
||||
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;
|
||||
@@ -329,6 +329,7 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
dev->gp_signals[j].gp_pid = 0;
|
||||
nxsig_cancel_notification(&dev->gp_signals[j].gp_work);
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
|
||||
+5
-2
@@ -58,7 +58,6 @@
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
@@ -276,7 +275,7 @@ static void ft80x_notify(FAR struct ft80x_dev_s *priv,
|
||||
/* Yes.. Signal the client */
|
||||
|
||||
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 &= ~(1 << notify->id);
|
||||
ft80x_write_word(priv, FT80X_REG_INT_MASK, regval);
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&info->work);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -49,10 +49,9 @@
|
||||
*******************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/*******************************************************************************************
|
||||
* Public Types
|
||||
*******************************************************************************************/
|
||||
@@ -160,6 +159,7 @@ struct ft80x_i2cwrite_s
|
||||
struct ft80x_eventinfo_s
|
||||
{
|
||||
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 */
|
||||
int16_t pid; /* Send the notification to this task */
|
||||
};
|
||||
|
||||
@@ -104,6 +104,7 @@ struct phy_notify_s
|
||||
char intf[CONFIG_PHY_NOTIFICATION_MAXINTFLEN+1];
|
||||
pid_t pid;
|
||||
struct sigevent event;
|
||||
struct sigwork_s work;
|
||||
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 */
|
||||
|
||||
ret = nxsig_notification(client->pid, &client->event, SI_QUEUE);
|
||||
ret = nxsig_notification(client->pid, &client->event,
|
||||
SI_QUEUE, &client->work);
|
||||
if (ret < 0)
|
||||
{
|
||||
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();
|
||||
(void)arch_phy_irq(intf, NULL, NULL, NULL);
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&client->work);
|
||||
|
||||
/* Un-initialize the client entry */
|
||||
|
||||
client->assigned = false;
|
||||
|
||||
@@ -104,6 +104,7 @@ struct zc_open_s
|
||||
|
||||
pid_t do_pid;
|
||||
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 */
|
||||
|
||||
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);
|
||||
@@ -346,6 +348,10 @@ static int zc_close(FAR struct file *filep)
|
||||
priv->zu_open = opriv->do_flink;
|
||||
}
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&opriv->do_work);
|
||||
|
||||
/* And free the open structure */
|
||||
|
||||
kmm_free(opriv);
|
||||
|
||||
@@ -76,6 +76,7 @@ struct oneshot_dev_s
|
||||
/* Oneshot timer expiration notification information */
|
||||
|
||||
struct sigevent od_event; /* Signal info */
|
||||
struct sigwork_s od_work; /* Signal work */
|
||||
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 */
|
||||
|
||||
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 */
|
||||
|
||||
ret = ONESHOT_CANCEL(priv->od_lower, ts);
|
||||
nxsig_cancel_notification(&priv->od_work);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ struct rtc_alarminfo_s
|
||||
bool active; /* True: alarm is active */
|
||||
pid_t pid; /* Identifies task to be notified */
|
||||
struct sigevent event; /* Describe the way a task is to be notified */
|
||||
struct sigwork_s work; /* Signal work */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -196,7 +197,8 @@ static void rtc_alarm_callback(FAR void *priv, int alarmid)
|
||||
{
|
||||
/* 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 */
|
||||
@@ -227,7 +229,8 @@ static void rtc_periodic_callback(FAR void *priv, int alarmid)
|
||||
{
|
||||
/* 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 */
|
||||
@@ -566,6 +569,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
if (ret == OK)
|
||||
{
|
||||
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)
|
||||
{
|
||||
upperinfo->active = false;
|
||||
nxsig_cancel_notification(&upperinfo->work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ struct xbeenet_driver_s
|
||||
bool xd_notify_registered;
|
||||
pid_t xd_notify_pid;
|
||||
struct sigevent xd_notify_event;
|
||||
struct sigwork_s xd_notify_work;
|
||||
#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;
|
||||
nxsig_notification(priv->xd_notify_pid, &priv->xd_notify_event,
|
||||
SI_QUEUE);
|
||||
SI_QUEUE, &priv->xd_notify_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp)
|
||||
|
||||
/* The result -EINPROGRESS means that the transfer has not yet completed */
|
||||
|
||||
sigwork_init(&aiocbp->aio_sigwork);
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
|
||||
@@ -259,6 +259,7 @@ int aio_read(FAR struct aiocb *aiocbp)
|
||||
|
||||
/* The result -EINPROGRESS means that the transfer has not yet completed */
|
||||
|
||||
sigwork_init(&aiocbp->aio_sigwork);
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
|
||||
+2
-1
@@ -91,7 +91,8 @@ int aio_signal(pid_t pid, FAR struct aiocb *aiocbp)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
ferr("ERROR: nxsig_notification failed: %d\n", ret);
|
||||
|
||||
@@ -309,6 +309,7 @@ int aio_write(FAR struct aiocb *aiocbp)
|
||||
|
||||
/* The result -EINPROGRESS means that the transfer has not yet completed */
|
||||
|
||||
sigwork_init(&aiocbp->aio_sigwork);
|
||||
aiocbp->aio_result = -EINPROGRESS;
|
||||
aiocbp->aio_priv = NULL;
|
||||
|
||||
|
||||
+2
-1
@@ -43,9 +43,9 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -137,6 +137,7 @@ struct aiocb
|
||||
* 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() */
|
||||
FAR void *aio_priv; /* Used by signal handlers */
|
||||
};
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -144,6 +144,7 @@ struct gpio_operations_s
|
||||
struct gpio_signal_s
|
||||
{
|
||||
struct sigevent gp_event;
|
||||
struct sigwork_s gp_work;
|
||||
pid_t gp_pid; /* The task to be signaled */
|
||||
};
|
||||
|
||||
|
||||
@@ -43,13 +43,13 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <mqueue.h>
|
||||
#include <queue.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if CONFIG_MQ_MAXMSGSIZE > 0
|
||||
|
||||
@@ -117,6 +117,7 @@ struct mqueue_inode_s
|
||||
FAR struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */
|
||||
pid_t ntpid; /* Notification: Receiving Task's PID */
|
||||
struct sigevent ntevent; /* Notification description */
|
||||
struct sigwork_s ntwork; /* Notification work */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+47
-1
@@ -41,11 +41,35 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.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
|
||||
****************************************************************************/
|
||||
@@ -445,6 +469,7 @@ int nxsig_usleep(useconds_t usec);
|
||||
* 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
|
||||
* work - The work structure to queue
|
||||
*
|
||||
* Returned Value:
|
||||
* 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 */
|
||||
|
||||
@@ -192,7 +192,7 @@ static void lio_sighandler(int signo, siginfo_t *info, void *ucontext)
|
||||
/* Signal the client */
|
||||
|
||||
DEBUGVERIFY(nxsig_notification(sighand->pid, &sighand->sig,
|
||||
SI_ASYNCIO));
|
||||
SI_ASYNCIO, &aiocbp->aio_sigwork));
|
||||
|
||||
/* And free the container */
|
||||
|
||||
@@ -676,7 +676,8 @@ int lio_listio(int mode, FAR struct aiocb *const list[], int nent,
|
||||
}
|
||||
else
|
||||
{
|
||||
status = nxsig_notification(getpid(), sig, SI_ASYNCIO);
|
||||
status = nxsig_notification(getpid(), sig,
|
||||
SI_ASYNCIO, &aiocbp->aio_sigwork);
|
||||
if (status < 0 && ret == OK)
|
||||
{
|
||||
/* Something bad happened while performing the notification
|
||||
|
||||
@@ -116,6 +116,7 @@ void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
|
||||
memset(&msgq->ntevent, 0, sizeof(struct sigevent));
|
||||
msgq->ntpid = INVALID_PROCESS_ID;
|
||||
msgq->ntmqdes = NULL;
|
||||
nxsig_cancel_notification(&msgq->ntwork);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/mqueue.h>
|
||||
|
||||
#include "signal/signal.h"
|
||||
|
||||
#include "mqueue/mqueue.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.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));
|
||||
msgq->ntpid = INVALID_PROCESS_ID;
|
||||
msgq->ntmqdes = NULL;
|
||||
nxsig_cancel_notification(&msgq->ntwork);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/cancelpt.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 */
|
||||
|
||||
DEBUGVERIFY(nxsig_notification(pid, &event, SI_MESGQ));
|
||||
DEBUGVERIFY(nxsig_notification(pid, &event,
|
||||
SI_MESGQ, &msgq->ntwork));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#include <limits.h>
|
||||
#include <mqueue.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <nuttx/mqueue.h>
|
||||
|
||||
|
||||
@@ -48,10 +48,6 @@ ifeq ($(CONFIG_SIG_DEFAULT),y)
|
||||
CSRCS += sig_default.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIG_EVTHREAD),y)
|
||||
CSRCS += sig_evthread.c
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_POLL),y)
|
||||
CSRCS += sig_ppoll.c sig_pselect.c
|
||||
endif
|
||||
|
||||
@@ -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, ¬ify->nt_work, nxsig_evthread_worker,
|
||||
notify, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
kmm_free(notify);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SIG_EVTHREAD */
|
||||
@@ -50,6 +50,38 @@
|
||||
#include "sched/sched.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
|
||||
****************************************************************************/
|
||||
@@ -66,6 +98,7 @@
|
||||
* 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
|
||||
* work - The work structure to queue
|
||||
*
|
||||
* Returned Value:
|
||||
* 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",
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -207,9 +207,6 @@ 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);
|
||||
#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);
|
||||
FAR sigpendq_t *nxsig_remove_pendingsignal(FAR struct tcb_s *stcb, int signo);
|
||||
|
||||
+9
-8
@@ -44,9 +44,9 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
/****************************************************************************
|
||||
@@ -65,13 +65,14 @@ struct posix_timer_s
|
||||
{
|
||||
FAR struct posix_timer_s *flink;
|
||||
|
||||
uint8_t pt_flags; /* See PT_FLAGS_* definitions */
|
||||
uint8_t pt_crefs; /* Reference count */
|
||||
pid_t pt_owner; /* Creator of timer */
|
||||
int pt_delay; /* If non-zero, used to reset repetitive timers */
|
||||
int pt_last; /* Last value used to set watchdog */
|
||||
WDOG_ID pt_wdog; /* The watchdog that provides the timing */
|
||||
struct sigevent pt_event; /* Notification information */
|
||||
uint8_t pt_flags; /* See PT_FLAGS_* definitions */
|
||||
uint8_t pt_crefs; /* Reference count */
|
||||
pid_t pt_owner; /* Creator of timer */
|
||||
int pt_delay; /* If non-zero, used to reset repetitive timers */
|
||||
int pt_last; /* Last value used to set watchdog */
|
||||
WDOG_ID pt_wdog; /* The watchdog that provides the timing */
|
||||
struct sigevent pt_event; /* Notification information */
|
||||
struct sigwork_s pt_work;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -140,6 +140,10 @@ int timer_release(FAR struct posix_timer_s *timer)
|
||||
|
||||
(void)wd_delete(timer->pt_wdog);
|
||||
|
||||
/* Cancel any pending notification */
|
||||
|
||||
nxsig_cancel_notification(&timer->pt_work);
|
||||
|
||||
/* Release the timer structure */
|
||||
|
||||
timer_free(timer);
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include "clock/clock.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)
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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 (value->it_value.tv_sec <= 0 && value->it_value.tv_nsec <= 0)
|
||||
|
||||
@@ -122,6 +122,7 @@ struct mac802154_chardevice_s
|
||||
bool md_notify_registered;
|
||||
pid_t md_notify_pid;
|
||||
struct sigevent md_notify_event;
|
||||
struct sigwork_s md_notify_work;
|
||||
|
||||
#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;
|
||||
nxsig_notification(dev->md_notify_pid, &dev->md_notify_event,
|
||||
SI_QUEUE);
|
||||
SI_QUEUE, &dev->md_notify_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -165,6 +165,7 @@ struct macnet_driver_s
|
||||
bool md_notify_registered;
|
||||
pid_t md_notify_pid;
|
||||
struct sigevent md_notify_event;
|
||||
struct sigwork_s md_notify_work;
|
||||
#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;
|
||||
nxsig_notification(priv->md_notify_pid, &priv->md_notify_event,
|
||||
SI_QUEUE);
|
||||
SI_QUEUE, &priv->md_notify_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user