summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-12 19:58:45 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-12 19:58:45 +0000
commit499c8c86de6757b39eaaf0f2b96a5b070f085b9b (patch)
tree84c6da5c61268158365bdafe58f546b34a0b8a91 /apps
parent5a180ec4940c993311eedddaa13194f9977968f1 (diff)
downloadnuttx-499c8c86de6757b39eaaf0f2b96a5b070f085b9b.tar.gz
nuttx-499c8c86de6757b39eaaf0f2b96a5b070f085b9b.tar.bz2
nuttx-499c8c86de6757b39eaaf0f2b96a5b070f085b9b.zip
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
Diffstat (limited to 'apps')
-rw-r--r--apps/ChangeLog.txt2
-rw-r--r--apps/examples/ostest/sighand.c58
2 files changed, 60 insertions, 0 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 6b63527a7..65d4d6134 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -462,4 +462,6 @@
* apps/examples/wlan: Remove non-functional example.
* apps/examples/ostest/vfork.c: Added a test of vfork().
* apps/exampes/posix_spawn: Added a test of poxis_spawn().
+ * apps/examples/ostest: Extend signal handler test to catch
+ death-of-child signals (SIGCHLD).
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();
}