sched/: Update signal default STOP action. If waitpid was called with the WUNTRACED then wake up waitpid. Also fix some compile problems.. How did this work before?

This commit is contained in:
Gregory Nutt 2018-09-02 13:51:52 -06:00
parent a6f9c6215d
commit 093348030e
10 changed files with 83 additions and 35 deletions

View File

@ -502,8 +502,9 @@ struct task_group_s
/* Simple mechanism used only when there is no support for SIGCHLD */
uint8_t tg_nwaiters; /* Number of waiters */
uint8_t tg_waitflags; /* User flags for waitpid behavior */
sem_t tg_exitsem; /* Support for waitpid */
int *tg_statloc; /* Location to return exit status */
FAR int *tg_statloc; /* Location to return exit status */
#endif
#ifndef CONFIG_DISABLE_PTHREAD

View File

@ -1,7 +1,8 @@
/********************************************************************************
* include/sched.h
*
* Copyright (C) 2007-2009, 2011, 2013, 2015-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011, 2013, 2015-2016 Gregory Nutt. All rights
* reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/sys/wait.h
*
* Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2013, 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -75,6 +75,7 @@
#define WEXITED (1 << 3) /* Wait for processes that have exited (2) */
#define WSTOPPED (1 << 4) /* Status for child stopped on signal (2) */
#define WNOWAIT (1 << 5) /* Keep the process in a waitable state (2) */
#define WCLAIMED (1 << 7) /* Non-standard (For internal OS use only) */
/****************************************************************************
* Public Type Definitions

View File

@ -117,8 +117,8 @@ 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);
int group_suspendchildren(FAR struct tcb_s *tcb);
int group_continue(FAR struct tcb_s *tcb);
#endif
#endif

View File

@ -66,25 +66,20 @@
* arg - Unused
*
* Returned Value:
* 0 (OK) on success; a negated errno value on failure.
* 0 (OK) always
*
****************************************************************************/
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)
if (rtcb != NULL)
{
ret = sched_resume(rtcb);
if (ret < 0)
{
serr("ERROR: Failed to resume %d: %d\n", ret, pid);
}
sched_continue(rtcb);
}
/* Always return zero. We need to visit each member of the group*/
@ -111,7 +106,7 @@ static int group_continue_handler(pid_t pid, FAR void *arg)
*
****************************************************************************/
int group_continue(FAR struct task_tcb_s *tcb)
int group_continue(FAR struct tcb_s *tcb)
{
int ret;
@ -120,7 +115,7 @@ int group_continue(FAR struct task_tcb_s *tcb)
*/
sched_lock();
ret = group_foreachchild(tcb->cmn.group, group_continue_handler, NULL);
ret = group_foreachchild(tcb->group, group_continue_handler, NULL);
sched_unlock();
return ret;
}

View File

@ -66,7 +66,7 @@
* arg - The PID of the thread to be retained.
*
* Returned Value:
* 0 (OK) on success; a negated errno value on failure.
* 0 (OK) always
*
****************************************************************************/

View File

@ -66,14 +66,13 @@
* arg - The PID of the thread to be retained.
*
* Returned Value:
* 0 (OK) on success; a negated errno value on failure.
* 0 (OK) always
*
****************************************************************************/
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 */
@ -84,11 +83,7 @@ static int group_suspendchildren_handler(pid_t pid, FAR void *arg)
rtcb = sched_gettcb(pid);
if (rtcb != NULL)
{
ret = sched_suspend(rtcb);
if (ret < 0)
{
serr("ERROR: Failed to suspend %d: %d\n", ret, pid);
}
sched_suspend(rtcb);
}
}
@ -117,7 +112,7 @@ static int group_suspendchildren_handler(pid_t pid, FAR void *arg)
*
****************************************************************************/
int group_suspendchildren(FAR struct task_tcb_s *tcb)
int group_suspendchildren(FAR struct tcb_s *tcb)
{
int ret;
@ -126,8 +121,8 @@ int group_suspendchildren(FAR struct task_tcb_s *tcb)
*/
sched_lock();
ret = group_foreachchild(tcb->cmn.group, group_suspendchildren_handler,
(FAR void *)((uintptr_t)tcb->cmn.pid));
ret = group_foreachchild(tcb->group, group_suspendchildren_handler,
(FAR void *)((uintptr_t)tcb->pid));
sched_unlock();
return ret;
}

View File

@ -1,7 +1,8 @@
/****************************************************************************
* sched/sched/sched_waitpid.c
*
* Copyright (C) 2011-2013, 2015, 2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-2013, 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
@ -231,9 +232,20 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
* others?
*/
if (stat_loc != NULL && group->tg_statloc == NULL)
if (group->tg_waitflags == 0)
{
/* Save the waitpid() options, setting the non-standard WCLAIMED bit to
* assure that tg_waitflags is non-zero.
*/
group->tg_waitflags = (uint8_t)options | WCLAIMED;
/* Save the return status location (which may be NULL) */
group->tg_statloc = stat_loc;
/* We are the waipid() instance that gets the return status */
mystat = true;
}
@ -267,7 +279,8 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
if (mystat)
{
group->tg_statloc = NULL;
group->tg_statloc = NULL;
group->tg_waitflags = 0;
}
errcode = -ret;

View File

@ -156,7 +156,7 @@ static const struct nxsig_defaction_s g_defactions[] =
* Name: nxsig_null_action
*
* Description:
* The do-nothing default signal actin handler.
* The do-nothing default signal action handler.
*
* Input Parameters:
* Standard signal handler parameters
@ -248,15 +248,55 @@ static void nxsig_stop_task(int signo)
#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.
* main thread of the task group if the this_task is a pthread.
*/
group_suspendchildren((FAR struct task_tcb_s *)rtcb);
group_suspendchildren(rtcb);
#endif
/* Then, finally, suspend this thread */
/* Lock the scheudler so this thread is not pre-empted until after we
* call sched_suspend().
*/
sched_lock();
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
/* Notify via waitpid if any parent is waiting for this task to EXIT
* or STOP. This action is only performed if WUNTRACED is set in the
* waitpid flags.
*/
if (group->tg_waitflags & WUNTRACED) != 0)
{
/* Return zero for exit status (we are not exiting, however) */
if (group->tg_statloc != NULL)
{
*group->tg_statloc = 0;
group->tg_statloc = NULL;
}
/* tg_waitflags == 0 means that the flags are available to another
* caller of waitpid().
*/
group->tg_waitflags = 0;
/* YWakeup any tasks waiting for this task to exit or stop. */
while (group->tg_exitsem.semcount < 0)
{
/* Wake up the thread */
nxsem_post(&group->tg_exitsem);
}
}
#endif
/* Then, finally, suspend this the final thread of the task group */
sched_suspend(rtcb);
sched_unlock();
}
/****************************************************************************

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/task/task_exithook.c
*
* Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2011-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
@ -536,7 +536,9 @@ static inline void task_exitwakeup(FAR struct tcb_s *tcb, int status)
{
/* Yes.. Wakeup any tasks waiting for this task to exit */
group->tg_statloc = NULL;
group->tg_statloc = NULL;
group->tg_waitflags = 0;
while (group->tg_exitsem.semcount < 0)
{
/* Wake up the thread */