sched/group and sched/signal: Some good but trivial stuff harvested from the suspend branch.

This commit is contained in:
Gregory Nutt
2018-08-29 15:50:01 -06:00
parent 1d04ef2f93
commit aaa660bae6
2 changed files with 47 additions and 28 deletions
+44 -20
View File
@@ -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 */
+3 -8
View File
@@ -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