I need to do following in a native thread:
1. Register for a signal like SIGALRM
2. Wait for the signal to trigger
3. Catch the signal and do some work
4. Go back to listening for the same signal
I'm able to do steps 1 and 2. However, I'm not able to come out of the
sigwait() call when SIGALRM fires. In the code I'm pasting below, I'm
also registering a signal handler for SIGALRM via sigaction(). This
handler gets called when SIGALRM fires, but sigwait() never comes out
of the wait.
Is that a limitation in NDK environment? Is there anything else I need
to do to come out of sigwait() when signal fires?
Thanks!
=======================================================
/*
signal processing thread
*/
void *signal_processor(void *arg)
{
int i;
sigset_t set;
int sig;
struct sigaction act;
/*
install signal handlers for SIGALRM
*/
memset (&act, '\0', sizeof(act));
/* Use the sa_sigaction field because the handles has
two additional parameters */
act.sa_sigaction = &hdl;
/* The SA_SIGINFO flag tells sigaction() to use the
sa_sigaction field, not sa_handler. */
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGALRM, &act, NULL) < 0)
{
LOGE("ERROR: sigaction - %s", strerror(errno));
}
for(i=0; i<3; i++)
{
LOGE("Setting Alarm");
alarm(5); /* timer will pop in five seconds */
LOGE("Waiting for signal");
/*
wait for any signal
*/
sigfillset(&set);
sig = 0;
sigwait(&set, &sig);
LOGE("Caught signal!!");
/*
handle the signal here, rather than in a signal handler
*/
switch(sig)
{
case SIGTERM:
LOGE("caught signal %d (SIGTERM)\n", sig);
pthread_exit(NULL);
case SIGALRM:
LOGE("caught signal %d (SIGALRM)\n", sig);
break;
default:
LOGE("caught signal %d\n", sig);
}
}
LOGE("Exiting signal_processor");
}
static void hdl (int sig, siginfo_t *siginfo, void *context)
{
LOGE("Sending PID: %ld, UID: %ld.\n",
(long)siginfo->si_pid, (long)siginfo->si_uid);
}
The signals you're waiting on must be blocked before calling
sigwait(), and you should not establish a handler for them.
The VM uses this sigwait() to catch SIGQUIT and SIGUSR1 for debugging
purposes; see dalvik/vm/Init.c and dalvik/vm/SignalCatcher.c for
examples (search for "SIGUSR1").
http://android.git.kernel.org/?p=platform/dalvik.git;a=blob;f=vm/Init.c;h=c46de253b326ac900b862147a7ef777a731bbb3e;hb=HEAD
http://android.git.kernel.org/?p=platform/dalvik.git;a=blob;f=vm/SignalCatcher.c;h=e187aeb3c42672b61be23eafb524e3fa8c296b2e;hb=HEAD
The problem wasn't with the sigwait(). The issue was with the SIGALRM.
When I replaced SIGALRM with SIGUSR2, the execution flow worked fine.
Eventually I was planning on using SIGUSR2 in my application anyway.
So this indeed is a good news that SIGUSR2 works fine with sigwait().
Regards
B
On Apr 1, 11:06 pm, fadden <fad...@android.com> wrote:
> On Apr 1, 6:56 pm, B Zen <biren...@gmail.com> wrote:
>
> > I need to do following in a native thread:
> > 1. Register for a signal like SIGALRM
> > 2. Wait for the signal to trigger
> > 3. Catch the signal and do some work
> > 4. Go back to listening for the same signal
>
> > I'm able to do steps 1 and 2. However, I'm not able to come out of the
> > sigwait() call when SIGALRM fires. In the code I'm pasting below, I'm
> > also registering a signal handler for SIGALRM via sigaction(). This
> > handler gets called when SIGALRM fires, but sigwait() never comes out
> > of the wait.
>
> The signals you're waiting on must be blocked before calling
> sigwait(), and you should not establish a handler for them.
>
> The VM uses this sigwait() to catch SIGQUIT and SIGUSR1 for debugging
> purposes; see dalvik/vm/Init.c and dalvik/vm/SignalCatcher.c for
> examples (search for "SIGUSR1").
>
> http://android.git.kernel.org/?p=platform/dalvik.git;a=blob;f=vm/Init...
> http://android.git.kernel.org/?p=platform/dalvik.git;a=blob;f=vm/Sign...