mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
sched/group and sched/signal: Some good but trivial stuff harvested from the suspend branch.
This commit is contained in:
@@ -62,7 +62,7 @@
|
|||||||
* Callback from group_foreachchild that handles one member of the group.
|
* Callback from group_foreachchild that handles one member of the group.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* pid - The ID of the group member that may be signalled.
|
* pid - The ID of the group member that may be signaled.
|
||||||
* arg - The PID of the thread to be retained.
|
* arg - The PID of the thread to be retained.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
static int group_killchildren_handler(pid_t pid, FAR void *arg)
|
static int group_killchildren_handler(pid_t pid, FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb;
|
FAR struct tcb_s *rtcb;
|
||||||
int ret = OK;
|
int ret;
|
||||||
|
|
||||||
/* Cancel all threads except for the one specified by the argument */
|
/* Cancel all threads except for the one specified by the argument */
|
||||||
|
|
||||||
@@ -86,23 +86,39 @@ static int group_killchildren_handler(pid_t pid, FAR void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
rtcb = sched_gettcb(pid);
|
rtcb = sched_gettcb(pid);
|
||||||
rtcb->flags &= ~TCB_FLAG_NONCANCELABLE;
|
if (rtcb != NULL)
|
||||||
|
|
||||||
/* 'pid' could refer to the main task of the thread. That pid will
|
|
||||||
* appear in the group member list as well!
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
|
|
||||||
{
|
{
|
||||||
ret = pthread_cancel(pid);
|
/* This is a forced cancellation. Make sure that cancellation is
|
||||||
}
|
* not disabled by the task/thread. That bit would prevent
|
||||||
else
|
* pthread_cancel() or task_delete() from doing what they need
|
||||||
{
|
* to do.
|
||||||
ret = task_delete(pid);
|
*/
|
||||||
|
|
||||||
|
rtcb->flags &= ~TCB_FLAG_NONCANCELABLE;
|
||||||
|
|
||||||
|
/* 'pid' could refer to the main task of the thread. That pid
|
||||||
|
* will appear in the group member list as well!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((rtcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
|
||||||
|
{
|
||||||
|
ret = pthread_cancel(pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = task_delete(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
serr("ERROR: Failed to kill %d: %d\n", ret, pid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
/* Always return zero. We need to visit each member of the group*/
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -114,7 +130,8 @@ static int group_killchildren_handler(pid_t pid, FAR void *arg)
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Delete all children of a task except for the specified task. This is
|
* Delete all children of a task except for the specified task. This is
|
||||||
* used by the task restart logic. When the main task is restarted,
|
* used by the task restart logic and by the default signal handling
|
||||||
|
* abnormal termination logic. When the main task is restarted or killed,
|
||||||
* all of its child pthreads must be terminated.
|
* all of its child pthreads must be terminated.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
@@ -123,14 +140,21 @@ static int group_killchildren_handler(pid_t pid, FAR void *arg)
|
|||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int group_killchildren(FAR struct task_tcb_s *tcb)
|
int group_killchildren(FAR struct task_tcb_s *tcb)
|
||||||
{
|
{
|
||||||
return group_foreachchild(tcb->cmn.group, group_killchildren_handler,
|
int ret;
|
||||||
(FAR void *)((uintptr_t)tcb->cmn.pid));
|
|
||||||
|
/* 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_killchildren_handler,
|
||||||
|
(FAR void *)((uintptr_t)tcb->cmn.pid));
|
||||||
|
sched_unlock();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_GROUP_MEMBERS */
|
#endif /* HAVE_GROUP_MEMBERS */
|
||||||
|
|||||||
@@ -165,18 +165,13 @@ static void nxsig_abnormal_termination(int signo)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_GROUP_MEMBERS
|
#ifdef HAVE_GROUP_MEMBERS
|
||||||
/* Kill of of the children of the task. If we are running on a pthread,
|
/* Kill of of the children of the task. This will not kill the currently
|
||||||
* this will not kill the currently running task/pthread (this_task). It
|
* running task/pthread (this_task). It will kill the main thread of the
|
||||||
* will kill the main thread of the task group if the this_task is a
|
* task group if the this_task is a
|
||||||
* pthread.
|
* pthread.
|
||||||
*
|
|
||||||
* Lock the scheduler so that there this thread will not lose priority
|
|
||||||
* until all of its children are dead.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sched_lock();
|
|
||||||
group_killchildren((FAR struct task_tcb_s *)rtcb);
|
group_killchildren((FAR struct task_tcb_s *)rtcb);
|
||||||
sched_unlock();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
|
|||||||
Reference in New Issue
Block a user