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:
patacongo
2013-01-12 19:58:45 +00:00
parent db161f73bc
commit b58281cab8
136 changed files with 540 additions and 164 deletions
+58
View File
@@ -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();
}