From 499c8c86de6757b39eaaf0f2b96a5b070f085b9b Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 12 Jan 2013 19:58:45 +0000 Subject: Fix a *critical* bug in the task exit logic. Implements SIGCHILD git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5513 42af7a65-404d-4744-a932-0658087f49c3 --- apps/examples/ostest/sighand.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'apps/examples/ostest/sighand.c') diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c index eabfe5646..63d9590d9 100644 --- a/apps/examples/ostest/sighand.c +++ b/apps/examples/ostest/sighand.c @@ -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(); } -- cgit v1.2.3