Losing signal problem

I'm newbie in UNIX programming, I have a problem with signals. I'm writing multithread program, where threads can die at any moment. When thread dies it generates signal SIGUSR1 to main thread and then thread dies. Main thread gets a signal and waits for thread dead.

I wrote program like this:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <signal.h>
#include <semaphore.h>

#define THREADS 3

int threads;
sem_t sem;

void signal_usr1_act(int signo,siginfo_t *inf,void *vd)
{
pthread_t *s;
fprintf(stderr,"Got USR1\n");
s=inf->si_value.sival_ptr;
pthread_join(*s,NULL);
threads--;
fprintf(stderr,"Joined!\n");
if(threads==0)sem_post(&sem);
}

void *thread_func(void*a)
{
union sigval sig_value;
sig_value.sival_ptr=a;
fprintf(stderr,"sending signal\n");
sigqueue(getpid(),SIGUSR1,sig_value); // sending pthread_t*
fprintf(stderr,"sleeping\n");
system("sleep 2"); // Any operation to make a delay
fprintf(stderr,"Stop sleeping\n");
}

int main(int argc,char **argv)
{
int i;
pthread_t pts[THREADS];
sigset_t new_mask,old_mask;
struct sigaction new_sig,old_sig;
// Adding signal action
new_sig.sa_sigaction=signal_usr1_act;
new_sig.sa_flags=SA_SIGINFO;
sigemptyset(&new_sig.sa_mask);
sigfillset(&new_sig.sa_mask);
sigaction(SIGUSR1,&new_sig,&old_sig);
// some initialisation stuff
sem_init(&sem,0,0);
threads=THREADS;
// creating mask
sigemptyset(&new_mask);
sigfillset(&new_mask);
// creating threads
pthread_sigmask(SIG_BLOCK,&new_mask,&old_mask);
for(i=0;i<THREADS;i++)
{
pthread_create(pts+i,NULL,thread_func,pts+i);
// And some other code, where we should block signals
}
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
// Waiting for threads
do{
pthread_sigmask(SIG_BLOCK,&new_mask,NULL);
fprintf(stderr,"Main is locked! Waiting for %d threads\n",threads);
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
}while(sem_wait(&sem)<0);
sem_destroy(&sem);
return 0;
}

I've got a problem: some signals were not sended/received and I've got deadlock (main thread waits for signal, but signal never comes).
Program prints:

Main is locked! Waiting for 3 threads
sending signal
sleeping
Got USR1
sending signal
sleeping
sending signal
sleeping
Stop sleeping
Stop sleeping
Joined!
Got USR1
Joined!
Main is locked! Waiting for 1 threads
Stop sleeping

After it program locks.

Why some signals were not received? Program should send/recive 3 SIGUSR1 and exit, but there are only 2 SIGUSR1. Why?

Look up "async signal safe"

Hint: pthread_join() isn't "async signal safe".

Why "signal safety" may change something? Signals are blocked, when signal action called.

Ok, I've found list of async-signal-safe functions. I've replaced pthread_join by sleep(3) and system() by sleep(2) - nothing changed - I'm getting deadlock ( sleep() is async-signal-safe function ) .

It means, you're not allowed to call pthread_join(*s,NULL); inside a signal handler, and the results can't be predicted when you do so. It may work and betray you in strange ways later. It may do incorrect things in a less than obvious way. It may blow up immediately. It may work in this system but fail when ported to another system or your kernel is upgraded. In short, you're not supposed to do it.

The only signal-safe IPC I know of is sem_wait.

Is fprintf() listed as an async-signal safe call?

fprintf is not async-signal safe, but replacing it by write(STDERR_FILENO,...) did not change anything - received only 1 SIGUSR1 of 3.