mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-27 07:33:33 +08:00
Fix a *critical* bug in the task exit logic. Implements SIGCHILD
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5513 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -54,12 +54,32 @@ static sem_t sem;
|
||||
static bool sigreceived = false;
|
||||
static bool threadexited = false;
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
static void death_of_child(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
|
||||
|
||||
if (info)
|
||||
{
|
||||
printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n",
|
||||
getpid(), signo, info->si_code, info->si_pid, info->si_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("death_of_child: PID %d received signal=%d (no info?)\n",
|
||||
getpid(), signo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
sigset_t oldset;
|
||||
sigset_t allsigs;
|
||||
int status;
|
||||
|
||||
/* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
|
||||
|
||||
printf("wakeup_action: Received signal %d\n" , signo);
|
||||
|
||||
sigreceived = true;
|
||||
@@ -186,6 +206,11 @@ static int waiter_main(int argc, char *argv[])
|
||||
|
||||
void sighand_test(void)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
sigset_t sigset;
|
||||
#endif
|
||||
struct sched_param param;
|
||||
union sigval sigvalue;
|
||||
pid_t waiterpid;
|
||||
@@ -195,6 +220,32 @@ void sighand_test(void)
|
||||
printf("sighand_test: Initializing semaphore to 0\n" );
|
||||
sem_init(&sem, 0, 0);
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
printf("sighand_test: Unmasking SIGCHLD\n");
|
||||
|
||||
(void)sigemptyset(&sigset);
|
||||
(void)sigaddset(&sigset, SIGCHLD);
|
||||
status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("sighand_test: ERROR sigprocmask failed, status=%d\n",
|
||||
status);
|
||||
}
|
||||
|
||||
printf("sighand_test: Registering SIGCHLD handler\n" );
|
||||
act.sa_sigaction = death_of_child;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigfillset(&act.sa_mask);
|
||||
(void)sigdelset(&act.sa_mask, SIGCHLD);
|
||||
|
||||
status = sigaction(SIGCHLD, &act, &oact);
|
||||
if (status != OK)
|
||||
{
|
||||
printf("waiter_main: ERROR sigaction failed, status=%d\n" , status);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start waiter thread */
|
||||
|
||||
printf("sighand_test: Starting waiter task\n" );
|
||||
@@ -262,6 +313,13 @@ void sighand_test(void)
|
||||
printf("sighand_test: ERROR signal handler did not run\n" );
|
||||
}
|
||||
|
||||
/* Detach the signal handler */
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
act.sa_sigaction = SIG_DFL;
|
||||
status = sigaction(SIGCHLD, &act, &oact);
|
||||
#endif
|
||||
|
||||
printf("sighand_test: done\n" );
|
||||
FFLUSH();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user