|
Szabolcs Nagy |
90e311 |
// commit: 370f78f2c80c64b7b0780a01e672494a26b5678e 2011-03-09
|
|
Szabolcs Nagy |
f9ba40 |
// commit: 0bed7e0acfd34e3fb63ca0e4d99b7592571355a9 2011-03-09
|
|
Szabolcs Nagy |
f9ba40 |
// raise should be robust against async fork in a signal handler
|
|
Szabolcs Nagy |
90e311 |
#include <pthread.h>
|
|
Szabolcs Nagy |
90e311 |
#include <signal.h>
|
|
Szabolcs Nagy |
90e311 |
#include <errno.h>
|
|
Szabolcs Nagy |
90e311 |
#include <string.h>
|
|
Szabolcs Nagy |
90e311 |
#include <sys/wait.h>
|
|
Szabolcs Nagy |
90e311 |
#include <unistd.h>
|
|
Szabolcs Nagy |
90e311 |
#include "test.h"
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
static volatile int c0;
|
|
Szabolcs Nagy |
90e311 |
static volatile int c1;
|
|
Szabolcs Nagy |
90e311 |
static volatile int child;
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
static void handler0(int sig)
|
|
Szabolcs Nagy |
90e311 |
{
|
|
Szabolcs Nagy |
90e311 |
c0++;
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
static void handler1(int sig)
|
|
Szabolcs Nagy |
90e311 |
{
|
|
Szabolcs Nagy |
90e311 |
c1++;
|
|
Szabolcs Nagy |
90e311 |
switch (fork()) {
|
|
Szabolcs Nagy |
90e311 |
case 0: child=1; break;
|
|
Szabolcs Nagy |
90e311 |
case -1: t_error("fork failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
static void *start(void *arg)
|
|
Szabolcs Nagy |
90e311 |
{
|
|
Szabolcs Nagy |
90e311 |
int i,r,s;
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
for (i = 0; i < 1000; i++) {
|
|
Szabolcs Nagy |
90e311 |
r = raise(SIGRTMIN);
|
|
Szabolcs Nagy |
90e311 |
if (r)
|
|
Szabolcs Nagy |
90e311 |
t_error("raise failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
if (c0 != 1000)
|
|
Szabolcs Nagy |
90e311 |
t_error("lost signals: got %d, wanted 1000 (ischild %d forks %d)\n", c0, child, c1);
|
|
Szabolcs Nagy |
90e311 |
if (child)
|
|
Szabolcs Nagy |
90e311 |
_exit(t_status);
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
/* make sure we got all pthread_kills, then wait the forked children */
|
|
Szabolcs Nagy |
90e311 |
while (c1 < 100);
|
|
Szabolcs Nagy |
90e311 |
for (i = 0; i < 100; i++) {
|
|
Szabolcs Nagy |
90e311 |
r = wait(&s);
|
|
Szabolcs Nagy |
90e311 |
if (r == -1)
|
|
Szabolcs Nagy |
90e311 |
t_error("wait failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
90e311 |
else if (!WIFEXITED(s) || WTERMSIG(s))
|
|
Szabolcs Nagy |
90e311 |
t_error("child failed: pid:%d status:%d\n", r, s);
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
return 0;
|
|
Szabolcs Nagy |
90e311 |
}
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
90e311 |
int main(void)
|
|
Szabolcs Nagy |
90e311 |
{
|
|
Szabolcs Nagy |
90e311 |
pthread_t t;
|
|
Szabolcs Nagy |
90e311 |
void *p;
|
|
Szabolcs Nagy |
90e311 |
int r, i, s;
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
6ac6e4 |
if (signal(SIGRTMIN, handler0) == SIG_ERR)
|
|
Szabolcs Nagy |
6ac6e4 |
t_error("registering signal handler failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
6ac6e4 |
if (signal(SIGRTMIN+1, handler1) == SIG_ERR)
|
|
Szabolcs Nagy |
6ac6e4 |
t_error("registering signal handler failed: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
90e311 |
|
|
Szabolcs Nagy |
6ac6e4 |
r = pthread_create(&t, 0, start, 0);
|
|
Szabolcs Nagy |
6ac6e4 |
if (r)
|
|
Szabolcs Nagy |
6ac6e4 |
t_error("pthread_create failed: %s\n", strerror(r));
|
|
Szabolcs Nagy |
6ac6e4 |
for (i = 0; i < 100; i++) {
|
|
Szabolcs Nagy |
6ac6e4 |
r = pthread_kill(t, SIGRTMIN+1);
|
|
Szabolcs Nagy |
6ac6e4 |
if (r)
|
|
Szabolcs Nagy |
6ac6e4 |
t_error("phread_kill failed: %s\n", strerror(r));
|
|
Szabolcs Nagy |
6ac6e4 |
}
|
|
Szabolcs Nagy |
6ac6e4 |
r = pthread_join(t,&p);
|
|
Szabolcs Nagy |
6ac6e4 |
if (r)
|
|
Szabolcs Nagy |
6ac6e4 |
t_error("pthread_join failed: %s\n", strerror(r));
|
|
Szabolcs Nagy |
90e311 |
return t_status;
|
|
Szabolcs Nagy |
90e311 |
}
|