This commit adds support for default signal actions for SIGSTOP, SIGSTP, and SIGCONT.
Squashed commit of the following: Add procfs support to show stopped tasks. Add nxsig_action() to solve a chicken and egg problem: We needed to use sigaction to set default actions, but sigaction() would refuse to set actions if the default actions could not be caught or ignored. sched/signal: Add configuration option to selectively enabled/disable default signal actions for SIGSTOP/SIGSTP/SIGCONT and SIGKILL/SIGINT. Fix some compilation issues. sched/sched: Okay.. I figured out a way to handle state changes that may occur while they were stopped. If a task/thread was already blocked when SIGSTOP/SIGSTP was received, it will restart in the running state. I will appear that to the task/thread that the blocked condition was interrupt by a signal and returns the EINTR error. sched/group and sched/sched: Finish framework for continue/resume logic. sched/signal: Roughing out basic structure to support task suspend/resume
This commit is contained in:
parent
20fc3ebcdd
commit
a7265d71c6
@ -4874,10 +4874,63 @@ interface of the same name.
|
||||
The signal handler is a user-supplied function that is bound to a specific signal and performs whatever actions are necessary whenever the signal is received.
|
||||
</p>
|
||||
<p>
|
||||
There are no predefined actions for any signal.
|
||||
By default, here are no predefined actions for any signal.
|
||||
The default action for all signals (i.e., when no signal handler has been supplied by the user) is to ignore the signal.
|
||||
In this sense, all NuttX are <i>real time</i> signals.
|
||||
In this sense, all NuttX are <i>real time</i> signals by default.
|
||||
If the configuration option <code>CONFIG_SIG_DEFAULT=y</code> is included, some signals will perform their default actions dependent upon addition configuration settings as summarized in the following table:
|
||||
</p>
|
||||
<p><ul><table>
|
||||
<tr>
|
||||
<th>Signal</th>
|
||||
<th>Action</th>
|
||||
<th>Additional Configuration</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGUSR1</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGUSR1_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGUSR2</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGUSR2_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGALRM</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGALRM_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGPOLL</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGPOLL_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGSTOP</code></td>
|
||||
<td>Suspend task</td>
|
||||
<td><code>CONFIG_SIG_SIGSTOP_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGSTP</code></td>
|
||||
<td>Suspend task</td>
|
||||
<td><code>CONFIG_SIG_SIGSTOP_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGCONT</code></td>
|
||||
<td>Resume task</td>
|
||||
<td><code>CONFIG_SIG_SIGSTOP_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGINT</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGKILL_ACTION</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SIGKILL</code></td>
|
||||
<td>Abnormal Termination</td>
|
||||
<td><code>CONFIG_SIG_SIGKILL_ACTION</code></td>
|
||||
</tr>
|
||||
</table></ul></p>
|
||||
<p>
|
||||
Tasks may also suspend themselves and wait until a signal is received.
|
||||
</p>
|
||||
|
22
TODO
22
TODO
@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated August 26, 2018)
|
||||
NuttX TODO List (Last updated August 30, 2018)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@ -579,10 +579,24 @@ o Signals (sched/signal, arch/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Title: STANDARD SIGNALS
|
||||
Description: 'Standard' signals and signal actions are not supported.
|
||||
(e.g., SIGINT, SIGSEGV, etc). Default is only SIG_IGN.
|
||||
Description: 'Standard' signals and signal actions are not fully
|
||||
supported. The SIGCHLD signal is supported and, if the
|
||||
option CONFIG_SIG_DEFAULT=y is included, some signals will
|
||||
perform their default actions (dependent upon addition
|
||||
configuration settings):
|
||||
|
||||
Signal Action Additional Configuration
|
||||
------- -------------------- -------------------------
|
||||
SIGUSR1 Abnormal Termination CONFIG_SIG_SIGUSR1_ACTION
|
||||
SIGUSR2 Abnormal Termination CONFIG_SIG_SIGUSR2_ACTION
|
||||
SIGALRM Abnormal Termination CONFIG_SIG_SIGALRM_ACTION
|
||||
SIGPOLL Abnormal Termination CONFIG_SIG_SIGPOLL_ACTION
|
||||
SIGSTOP Suspend task CONFIG_SIG_SIGSTOP_ACTION
|
||||
SIGSTP Suspend task CONFIG_SIG_SIGSTOP_ACTION
|
||||
SIGCONT Resume task CONFIG_SIG_SIGSTOP_ACTION
|
||||
SIGINT Abnormal Termination CONFIG_SIG_SIGKILL_ACTION
|
||||
SIGKILL Abnormal Termination CONFIG_SIG_SIGKILL_ACTION
|
||||
|
||||
Update: SIGCHLD is supported if so configured.
|
||||
Status: Open. No further changes are planned.
|
||||
Priority: Low, required by standards but not so critical for an
|
||||
embedded system.
|
||||
|
@ -134,7 +134,7 @@ config SERIAL_TERMIOS
|
||||
config TTY_SIGINT
|
||||
bool "Support SIGINT"
|
||||
default n
|
||||
select SIG_DEFAULT
|
||||
select SIG_SIGKILL_ACTION
|
||||
depends on !DISABLE_SIGNALS && SERIAL_TERMIOS
|
||||
---help---
|
||||
Whether support Ctrl-c/x event. Enabled automatically for console
|
||||
|
@ -359,13 +359,16 @@ static FAR const char *g_statenames[] =
|
||||
#endif
|
||||
"Running",
|
||||
"Inactive",
|
||||
"Waiting,Semaphore",
|
||||
"Waiting,Semaphore"
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
"Waiting,Signal",
|
||||
, "Waiting,Signal"
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_MQUEUE
|
||||
"Waiting,MQ empty",
|
||||
"Waiting,MQ full"
|
||||
, "Waiting,MQ empty"
|
||||
, "Waiting,MQ full"
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
, "Stopped"
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -245,6 +245,10 @@ enum tstate_e
|
||||
#ifdef CONFIG_PAGING
|
||||
TSTATE_WAIT_PAGEFILL, /* BLOCKED - Waiting for page fill */
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
TSTATE_TASK_STOPPED, /* BLOCKED - Waiting for SIGCONT */
|
||||
#endif
|
||||
|
||||
NUM_TASK_STATES /* Must be last */
|
||||
};
|
||||
typedef enum tstate_e tstate_t;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -69,25 +70,27 @@
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
|
||||
# define _SIG_PROCMASK(h,s,o) nxsig_procmask(h,s,o)
|
||||
# define _SIG_QUEUE(p,s,v) nxsig_queue(p,s,v)
|
||||
# define _SIG_KILL(p,s) nxsig_kill(p,s);
|
||||
# define _SIG_WAITINFO(s,i) nxsig_timedwait(s,i,NULL)
|
||||
# define _SIG_NANOSLEEP(r,a) nxsig_nanosleep(r,a)
|
||||
# define _SIG_SLEEP(s) nxsig_sleep(s)
|
||||
# define _SIG_USLEEP(u) nxsig_usleep(u)
|
||||
# define _SIG_ERRNO(r) (-(r))
|
||||
# define _SIG_ERRVAL(r) (r)
|
||||
# define _SIG_PROCMASK(h,s,o) nxsig_procmask(h,s,o)
|
||||
# define _SIG_SIGACTION(s,a,o) nxsig_action(s,a,o,false)
|
||||
# define _SIG_QUEUE(p,s,v) nxsig_queue(p,s,v)
|
||||
# define _SIG_KILL(p,s) nxsig_kill(p,s);
|
||||
# define _SIG_WAITINFO(s,i) nxsig_timedwait(s,i,NULL)
|
||||
# define _SIG_NANOSLEEP(r,a) nxsig_nanosleep(r,a)
|
||||
# define _SIG_SLEEP(s) nxsig_sleep(s)
|
||||
# define _SIG_USLEEP(u) nxsig_usleep(u)
|
||||
# define _SIG_ERRNO(r) (-(r))
|
||||
# define _SIG_ERRVAL(r) (r)
|
||||
#else
|
||||
# define _SIG_PROCMASK(h,s,o) sigprocmask(h,s,o)
|
||||
# define _SIG_QUEUE(p,s,v) sigqueue(p,s,v)
|
||||
# define _SIG_KILL(p,s) kill(p,s);
|
||||
# define _SIG_WAITINFO(s,i) sigwaitinfo(s,i)
|
||||
# define _SIG_NANOSLEEP(r,a) nanosleep(r,a)
|
||||
# define _SIG_SLEEP(s) sleep(s)
|
||||
# define _SIG_USLEEP(u) usleep(u)
|
||||
# define _SIG_ERRNO(r) errno
|
||||
# define _SIG_ERRVAL(r) (-errno)
|
||||
# define _SIG_PROCMASK(h,s,o) sigprocmask(h,s,o)
|
||||
# define _SIG_SIGACTION(s,a,o) sigaction(s,a,o)
|
||||
# define _SIG_QUEUE(p,s,v) sigqueue(p,s,v)
|
||||
# define _SIG_KILL(p,s) kill(p,s);
|
||||
# define _SIG_WAITINFO(s,i) sigwaitinfo(s,i)
|
||||
# define _SIG_NANOSLEEP(r,a) nanosleep(r,a)
|
||||
# define _SIG_SLEEP(s) sleep(s)
|
||||
# define _SIG_USLEEP(u) usleep(u)
|
||||
# define _SIG_ERRNO(r) errno
|
||||
# define _SIG_ERRVAL(r) (-errno)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -138,6 +141,32 @@ struct timespec; /* Forward reference */
|
||||
|
||||
int nxsig_procmask(int how, FAR const sigset_t *set, FAR sigset_t *oset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_action
|
||||
*
|
||||
* Description:
|
||||
* This function allows the calling process to examine and/or specify the
|
||||
* action to be associated with a specific signal. This is a non-standard,
|
||||
* OS internal version of the standard sigaction() function. nxsig_action()
|
||||
* adds an additional parameter, force, that is used to set default signal
|
||||
* actions (which may not normally be settable). nxsig_action() does not
|
||||
* alter the errno variable.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sig - Signal of interest
|
||||
* act - Location of new handler
|
||||
* oact - Location to store only handler
|
||||
* force - Force setup of the signal handler
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxsig_action(int signo, FAR const struct sigaction *act,
|
||||
FAR struct sigaction *oact, bool force);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_queue
|
||||
*
|
||||
|
@ -169,17 +169,15 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIG_DEFAULT
|
||||
# ifndef CONFIG_SIG_INT
|
||||
# define SIGINT 6 /* Sent when ctrl-c event */
|
||||
# else
|
||||
# define SIGINT CONFIG_SIG_INT
|
||||
# endif
|
||||
# ifndef CONFIG_SIG_KILL
|
||||
# define SIGKILL 9 /* Sent from shell as 'kill -9 <task>' */
|
||||
# else
|
||||
# define SIGKILL CONFIG_SIG_KILL
|
||||
# endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
# define SIGSTOP CONFIG_SIG_STOP
|
||||
# define SIGSTP CONFIG_SIG_STP
|
||||
# define SIGCONT CONFIG_SIG_CONT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIG_SIGKILL_ACTION
|
||||
# define SIGKILL CONFIG_SIG_KILL
|
||||
# define SIGINT CONFIG_SIG_INT
|
||||
#endif
|
||||
|
||||
/* The following are non-standard signal definitions */
|
||||
|
@ -1201,30 +1201,52 @@ config SIG_SIGUSR1_ACTION
|
||||
bool "SIGUSR1"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGUSR1 (terminate the process)
|
||||
Enable the default action for SIGUSR1 (terminate the task)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
Backward compatible behavior would require that the application use
|
||||
sigaction() to ignore SIGUSR1.
|
||||
|
||||
config SIG_SIGUSR2_ACTION
|
||||
bool "SIGUSR2"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGUSR2 (terminate the process)
|
||||
Enable the default action for SIGUSR2 (terminate the task)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
Backward compatible behavior would require that the application use
|
||||
sigaction() to ignore SIGUSR2.
|
||||
|
||||
config SIG_SIGALRM_ACTION
|
||||
bool "SIGALRM"
|
||||
default n
|
||||
---help---
|
||||
Enable the default action for SIGALRM (terminate the process)
|
||||
Enable the default action for SIGALRM (terminate the task)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
Backward compatible behavior would require that the application use
|
||||
sigaction() to ignore SIGALRM.
|
||||
|
||||
config SIG_SIGPOLL_ACTION
|
||||
bool "SIGPOLL"
|
||||
default n
|
||||
depends on FS_AIO
|
||||
---help---
|
||||
Enable the default action for SIGPOLL (terminate the process)
|
||||
Enable the default action for SIGPOLL (terminate the task)
|
||||
Make sure that your applications are expecting this POSIX behavior.
|
||||
Backward compatible behavior would require that the application use
|
||||
sigaction() to ignore SIGPOLL.
|
||||
|
||||
config SIG_SIGSTOP_ACTION
|
||||
bool "SIGSTOP SIGSTP, and SIGCONT"
|
||||
default y
|
||||
---help---
|
||||
Enable the default action for SIGSTOP and SIGSTP (suspend the
|
||||
task) and SIGCONT (resume the task).
|
||||
|
||||
config SIG_SIGKILL_ACTION
|
||||
bool "SIGINT and SIGKILL"
|
||||
default y
|
||||
---help---
|
||||
Enable the default action for SIGINT and SIGKILL (terminate the
|
||||
task).
|
||||
|
||||
endif # SIG_DEFAULT
|
||||
|
||||
@ -1269,22 +1291,49 @@ config SIG_POLL
|
||||
The SIGPOLL signal is sent to a process when an asynchronous I/O
|
||||
event occurs (meaning it has been polled). Default: 5
|
||||
|
||||
config SIG_INT
|
||||
int "SIGINT"
|
||||
if SIG_DEFAULT
|
||||
|
||||
config SIG_STOP
|
||||
int "SIGSTOP"
|
||||
default 6
|
||||
depends on SIG_DEFAULT
|
||||
depends on SIG_SIGSTOP_ACTION
|
||||
---help---
|
||||
The SIGINT signal is sent to cause a task termination event (only
|
||||
if CONFIG_SIG_DEFAULT=y). SIGINT may be ignored or caught by the
|
||||
receiving task.
|
||||
Suspend/pause a task. SIGSTOP may not be caught or ignored.
|
||||
|
||||
config SIG_STP
|
||||
int "SIGSTP"
|
||||
default 7
|
||||
depends on SIG_SIGSTOP_ACTION
|
||||
---help---
|
||||
Suspend/pause a task. Unlike SIGSTOP, this signal can be caught or
|
||||
ignored.
|
||||
|
||||
config SIG_CONT
|
||||
int "SIGCONT"
|
||||
default 8
|
||||
depends on SIG_SIGSTOP_ACTION
|
||||
---help---
|
||||
Resume a suspended/paused task. SIGSTOP only has an action when
|
||||
send to a stopped task. SIGCONT is ignored by other task. SIGCONT
|
||||
may not be caught or ignored by a stopped task.
|
||||
|
||||
config SIG_KILL
|
||||
int "SIGKILL"
|
||||
default 9
|
||||
depends on SIG_DEFAULT
|
||||
depends on SIG_SIGKILL_ACTION
|
||||
---help---
|
||||
The SIGKILL signal is sent to cause a task termination event (only
|
||||
if CONFIG_SIG_DEFAULT=y). SIGKILL may not be caught or ignored.
|
||||
The SIGKILL signal is sent to cause a task termination event.
|
||||
SIGKILL may not be caught or ignored.
|
||||
|
||||
config SIG_INT
|
||||
int "SIGINT"
|
||||
default 10
|
||||
depends on SIG_SIGKILL_ACTION
|
||||
---help---
|
||||
The SIGINT signal is sent to cause a task termination event.
|
||||
SIGINT may be ignored or caught by the receiving task.
|
||||
|
||||
endif # SIG_DEFAULT
|
||||
|
||||
comment "Non-standard Signal Numbers"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# sched/group/Make.defs
|
||||
#
|
||||
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2014, 2018 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -52,6 +52,10 @@ ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
CSRCS += group_addrenv.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIG_SIGSTOP_ACTION),y)
|
||||
CSRCS += group_suspendchildren.c group_continue.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BINFMT_LOADABLE),y)
|
||||
CSRCS += group_exitinfo.c
|
||||
endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/group/group.h
|
||||
*
|
||||
* Copyright (C) 2007-2013, 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013, 2015, 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -116,6 +116,10 @@ FAR struct task_group_s *group_findbypid(pid_t pid);
|
||||
int group_foreachchild(FAR struct task_group_s *group,
|
||||
foreachchild_t handler, FAR void *arg);
|
||||
int group_killchildren(FAR struct task_tcb_s *tcb);
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
int group_suspendchildren(FAR struct task_tcb_s *tcb);
|
||||
int group_continue(FAR struct task_tcb_s *tcb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
128
sched/group/group_continue.c
Normal file
128
sched/group/group_continue.c
Normal file
@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
* sched/group/group_continue.c
|
||||
*
|
||||
* Copyright (C) 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 <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "group/group.h"
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_continue_handler
|
||||
*
|
||||
* Description:
|
||||
* Callback from group_foreachchild that handles one member of the group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pid - The ID of the group member that may be resumed.
|
||||
* arg - Unused
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int group_continue_handler(pid_t pid, FAR void *arg)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
int ret;
|
||||
|
||||
/* Resume all threads */
|
||||
|
||||
rtcb = sched_gettcb(pid);
|
||||
if (rtc != NULL)
|
||||
{
|
||||
ret = sched_resume(rtcb);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to resume %d: %d\n", ret, pid);
|
||||
}
|
||||
}
|
||||
|
||||
/* Always return zero. We need to visit each member of the group*/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_continue
|
||||
*
|
||||
* Description:
|
||||
* Resume all members of the task group. This is SIGCONT default signal
|
||||
* action logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - TCB of the task to be retained.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int group_continue(FAR struct task_tcb_s *tcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Lock the scheduler so that there this thread will not lose priority
|
||||
* until all of its children are suspended.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
ret = group_foreachchild(tcb->cmn.group, group_continue_handler, NULL);
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
135
sched/group/group_suspendchildren.c
Normal file
135
sched/group/group_suspendchildren.c
Normal file
@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
* sched/group/group_suspendchildren.c
|
||||
*
|
||||
* Copyright (C) 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 <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "group/group.h"
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_suspendchildren_handler
|
||||
*
|
||||
* Description:
|
||||
* Callback from group_foreachchild that handles one member of the group.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pid - The ID of the group member that may be suspended.
|
||||
* arg - The PID of the thread to be retained.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int group_suspendchildren_handler(pid_t pid, FAR void *arg)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
int ret;
|
||||
|
||||
/* Suspend all threads except for the one specified by the argument */
|
||||
|
||||
if (pid != (pid_t)((uintptr_t)arg))
|
||||
{
|
||||
/* Suspend this thread if it is still alive. */
|
||||
|
||||
rtcb = sched_gettcb(pid);
|
||||
if (rtcb != NULL)
|
||||
{
|
||||
ret = sched_suspend(rtcb);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to suspend %d: %d\n", ret, pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Always return zero. We need to visit each member of the group*/
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_suspendchildren
|
||||
*
|
||||
* Description:
|
||||
* Suspend all children of a task except for the specified task. This is
|
||||
* SIGSTP/SIGSTOP default signal action logic. When the main task is
|
||||
* suspended, all of its child pthreads must also be suspended.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - TCB of the task to be retained.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int group_suspendchildren(FAR struct task_tcb_s *tcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Lock the scheduler so that there this thread will not lose priority
|
||||
* until all of its children are suspended.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
ret = group_foreachchild(tcb->cmn.group, group_suspendchildren_handler,
|
||||
(FAR void *)((uintptr_t)tcb->cmn.pid));
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
@ -182,6 +182,12 @@ volatile dq_queue_t g_waitingformqnotfull;
|
||||
volatile dq_queue_t g_waitingforfill;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
/* This is the list of all tasks that have been stopped via SIGSTOP or SIGSTP */
|
||||
|
||||
volatile dq_queue_t g_stoppedtasks;
|
||||
#endif
|
||||
|
||||
/* This the list of all tasks that have been initialized, but not yet
|
||||
* activated. NOTE: This is the only list that is not prioritized.
|
||||
*/
|
||||
@ -300,6 +306,13 @@ const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] =
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
,
|
||||
{ /* TSTATE_TASK_STOPPED */
|
||||
&g_stoppedtasks,
|
||||
0 /* See tcb->prev_state */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This is the current initialization state. The level of initialization
|
||||
@ -397,6 +410,9 @@ void os_start(void)
|
||||
#endif
|
||||
#ifdef CONFIG_PAGING
|
||||
dq_init(&g_waitingforfill);
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
dq_init(&g_stoppedtasks);
|
||||
#endif
|
||||
dq_init(&g_inactivetasks);
|
||||
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
|
||||
|
@ -158,4 +158,5 @@ void irq_dispatch(int irq, FAR void *context)
|
||||
/* Then dispatch to the interrupt handler */
|
||||
|
||||
CALL_VECTOR(ndx, vector, irq, context, arg);
|
||||
UNUSED(ndx);
|
||||
}
|
||||
|
@ -54,6 +54,10 @@ CSRCS += sched_cpuselect.c sched_cpupause.c
|
||||
CSRCS += sched_getaffinity.c sched_setaffinity.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIG_SIGSTOP_ACTION),y)
|
||||
CSRCS += sched_suspend.c sched_continue.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||
CSRCS += sched_waitpid.c
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
|
@ -440,6 +440,11 @@ uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
|
||||
void sched_sporadic_lowpriority(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
void sched_suspend(FAR struct tcb_s *tcb);
|
||||
void sched_continue(FAR struct tcb_s *tcb);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#if defined(CONFIG_ARCH_GLOBAL_IRQDISABLE) || defined(CONFIG_ARCH_HAVE_FETCHADD)
|
||||
FAR struct tcb_s *this_task(void);
|
||||
|
81
sched/sched/sched_continue.c
Normal file
81
sched/sched/sched_continue.c
Normal file
@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
* sched/sched/sched_continue.c
|
||||
*
|
||||
* Copyright (C) 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 <sched.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_continue
|
||||
*
|
||||
* Description:
|
||||
* Resume the specified thread. This is normally calling indirectly
|
||||
* via group_continue();
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sched_continue(FAR struct tcb_s *tcb)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(tcb != NULL && tcb->task_state == TSTATE_TASK_STOPPED);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Simply restart the thread. If is was blocked before, it will awaken
|
||||
* with pterrno = EINTR and will appears as if it were awakened by a
|
||||
* signal. If pre-emption is not disabled this action could block this
|
||||
* task here!
|
||||
*/
|
||||
|
||||
up_unblock_task(tcb);
|
||||
leave_critical_section(flags);
|
||||
}
|
104
sched/sched/sched_suspend.c
Normal file
104
sched/sched/sched_suspend.c
Normal file
@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
* sched/sched/sched_suspend.c
|
||||
*
|
||||
* Copyright (C) 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 <sched.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_suspend
|
||||
*
|
||||
* Description:
|
||||
* Suspend/pause the specified thread. This is normally calling indirectly
|
||||
* via group_suspendchildren();
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sched_suspend(FAR struct tcb_s *tcb)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(tcb != NULL);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Check the current state of the task */
|
||||
|
||||
if (tcb->task_state >= FIRST_BLOCKED_STATE &&
|
||||
tcb->task_state <= LAST_BLOCKED_STATE)
|
||||
{
|
||||
/* Remove the TCB from the the blocked task list. */
|
||||
|
||||
sched_removeblocked(tcb);
|
||||
|
||||
/* Set the errno value to EINTR. The task will be restarted in the
|
||||
* running or runnable state and will appear to have awakened from
|
||||
* the block state by a signal.
|
||||
*/
|
||||
|
||||
tcb->pterrno = EINTR;
|
||||
|
||||
/* Move the TCB to the g_stoppedtasks list. */
|
||||
|
||||
sched_addblocked(tcb, TSTATE_TASK_STOPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The task was running or runnable before being stopped. Simply
|
||||
* block it in the stopped state. If tcb refers to this task, then
|
||||
* this action will block this task.
|
||||
*/
|
||||
|
||||
up_block_task(tcb, TSTATE_TASK_STOPPED);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# sched/signal/Make.defs
|
||||
#
|
||||
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2014, 2018 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
#include <queue.h>
|
||||
#include <sched.h>
|
||||
@ -94,7 +95,7 @@ static FAR sigactq_t *nxsig_alloc_action(void)
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigaction
|
||||
* Name: nxsig_action and sigaction
|
||||
*
|
||||
* Description:
|
||||
* This function allows the calling process to examine and/or specify the
|
||||
@ -123,16 +124,28 @@ static FAR sigactq_t *nxsig_alloc_action(void)
|
||||
* original signal mask is restored.
|
||||
*
|
||||
* Once an action is installed for a specific signal, it remains installed
|
||||
* until another action is explicitly requested by another call to sigaction().
|
||||
* until another action is explicitly requested by another call to
|
||||
* sigaction().
|
||||
*
|
||||
* nxsig_action() is an internal version of sigaction that adds an
|
||||
* additional parameter, force, that is used to set default signal actions
|
||||
* (which may not normally be settable). nxsig_action() does not alter the
|
||||
* errno variable.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sig - Signal of interest
|
||||
* act - Location of new handler
|
||||
* oact - Location to store only handler
|
||||
* sig - Signal of interest
|
||||
* act - Location of new handler
|
||||
* oact - Location to store only handler
|
||||
* force - Force setup of the signal handler, even if it cannot normally
|
||||
* be caught or ignored (nxsig_action only)
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK), or -1 (ERROR) if the signal number is invalid.
|
||||
* (errno is not set)
|
||||
* nxsig_action:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure
|
||||
* sigaction:
|
||||
* Zero (OK) is returned on success; -1 (ERROR) is returned on any
|
||||
* failure if the signal number is invalid with the errno set appropriately
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
@ -145,8 +158,8 @@ static FAR sigactq_t *nxsig_alloc_action(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sigaction(int signo, FAR const struct sigaction *act,
|
||||
FAR struct sigaction *oact)
|
||||
int nxsig_action(int signo, FAR const struct sigaction *act,
|
||||
FAR struct sigaction *oact, bool force)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct task_group_s *group;
|
||||
@ -164,8 +177,7 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
|
||||
if (!GOOD_SIGNO(signo))
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SIG_DEFAULT
|
||||
@ -173,11 +185,10 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
* caught or ignored.
|
||||
*/
|
||||
|
||||
if (act != NULL &&
|
||||
(act->sa_handler != SIG_DFL && !nxsig_iscatchable(signo)))
|
||||
if (act != NULL && !force && act->sa_handler != SIG_DFL &&
|
||||
!nxsig_iscatchable(signo))
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -316,8 +327,7 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
|
||||
if (!sigact)
|
||||
{
|
||||
set_errno(ENOMEM);
|
||||
return ERROR;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Put the signal number in the queue entry */
|
||||
@ -339,6 +349,23 @@ int sigaction(int signo, FAR const struct sigaction *act,
|
||||
return OK;
|
||||
}
|
||||
|
||||
int sigaction(int signo, FAR const struct sigaction *act,
|
||||
FAR struct sigaction *oact)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* nxsig_action() does all of the work */
|
||||
|
||||
ret = nxsig_action(signo, act, oact, false);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_release_action
|
||||
*
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include "group/group.h"
|
||||
#include "sched/sched.h"
|
||||
@ -80,7 +81,9 @@ struct nxsig_defaction_s
|
||||
|
||||
/* Default actions */
|
||||
|
||||
static void nxsig_null_action(int signo);
|
||||
static void nxsig_abnormal_termination(int signo);
|
||||
static void nxsig_stop_task(int signo);
|
||||
|
||||
/* Helpers */
|
||||
|
||||
@ -116,8 +119,15 @@ static const struct nxsig_defaction_s g_defactions[] =
|
||||
#ifdef CONFIG_SIG_SIGPOLL_ACTION
|
||||
{ SIGPOLL, 0, nxsig_abnormal_termination },
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
{ SIGSTOP, SIG_FLAG_NOCATCH, nxsig_stop_task },
|
||||
{ SIGSTP, 0, nxsig_stop_task },
|
||||
{ SIGCONT, SIG_FLAG_NOCATCH, nxsig_null_action },
|
||||
#endif
|
||||
#ifdef CONFIG_SIG_SIGKILL_ACTION
|
||||
{ SIGINT, 0, nxsig_abnormal_termination },
|
||||
{ SIGKILL, SIG_FLAG_NOCATCH, nxsig_abnormal_termination }
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NACTIONS (sizeof(g_defactions) / sizeof(struct nxsig_defaction_s))
|
||||
@ -142,6 +152,24 @@ static const struct nxsig_defaction_s g_defactions[] =
|
||||
* - Continue the process, if it is stopped; otherwise, ignore the signal.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_null_action
|
||||
*
|
||||
* Description:
|
||||
* The do-nothing default signal actin handler.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard signal handler parameters
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nxsig_null_action(int signo)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_abnormal_termination
|
||||
*
|
||||
@ -195,6 +223,42 @@ static void nxsig_abnormal_termination(int signo)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_stop_task
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for the abnormal termination default action.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard signal handler parameters
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nxsig_stop_task(int signo)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = (FAR struct tcb_s *)this_task();
|
||||
|
||||
/* Careful: In the multi-threaded task, the signal may be handled on a
|
||||
* child pthread.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
/* Suspend of of the children of the task. This will not suspend the
|
||||
* currently running task/pthread (this_task). It will suspend the
|
||||
* main thread of the task group if the this_task is a pthread.
|
||||
*/
|
||||
|
||||
group_suspendchildren((FAR struct task_tcb_s *)rtcb);
|
||||
#endif
|
||||
|
||||
/* Then, finally, suspend this thread */
|
||||
|
||||
sched_suspend(rtcb);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsig_default_action
|
||||
*
|
||||
@ -260,13 +324,14 @@ static void nxsig_setup_default_action(FAR struct task_group_s *group,
|
||||
|
||||
/* Attach the signal handler.
|
||||
*
|
||||
* NOTE: sigaction will call nxsig_default(tcb, action, false)
|
||||
* NOTE: nxsig_action will call nxsig_default(tcb, action, false).
|
||||
* Don't be surprised.
|
||||
*/
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_handler = info->action;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
(void)sigaction(info->signo, &sa, NULL);
|
||||
(void)nxsig_action(info->signo, &sa, NULL, true);
|
||||
|
||||
/* Indicate that the default signal handler has been attached */
|
||||
|
||||
|
@ -402,6 +402,22 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
|
||||
nxmq_wait_irq(stcb, EINTR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIG_SIGSTOP_ACTION
|
||||
/* If the task was stopped by SIGSTOP or SIGSTP, then unblock the task
|
||||
* if SIGCONT is received.
|
||||
*/
|
||||
|
||||
if (stcb->task_state == TSTATE_TASK_STOPPED &&
|
||||
info->si_signo == SIGCONT)
|
||||
{
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
group_continue(stcb);
|
||||
#else
|
||||
sched_continue(stcb);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
Loading…
x
Reference in New Issue
Block a user