Search code examples
linuxunixpthreadssignalsposix

Why pthread_mutex_lock is not marked as async-signal safe?


You see, sem_post is marked as async-signal safe. But why pthread_mutex_lock is not marked as async-signal safe, while the following program give you the illusion that it is actually async-signal safe?

void handle(int arg){
    printf("I wake up!\n");
}
int main()
{
    signal(SIGHUP, handle);
    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&lock);
    printf("gonna be blocked\n");

    pthread_mutex_lock(&lock);
    pthread_mutex_unlock(&lock);
    return 0;
}

kill -hup $pid will have it print out something. But the lock is still not acquired and program is blocked(I mean, it does not finish), which give me the impression that it is asynchronous signal safe.

You can consult Advanced unix programming environment book, or man sigaction to get async-signal safe function list.


Solution

  • But why pthread_mutex_lock is not marked as async-signal safe

    Because it isn't.

    while the following program give you the illusion that it is actually async-signal safe?

    Your program has nothing to do with async signal safety. Any conclusion about async signal safety your derived from this test program is plain wrong.

    Async signal safety is about being able to call the function from an async signal handler.

    To see that pthread_mutex_lock isn't async signal safe, write a program with 3 threads: one doing pthread_mutex_lock and pthread_mutex_unlock in a tight loop, one doing the same on the same mutex from a signal handler, and a third one that sends an unending stream of SIGHUPs to the process.

    If pthread_mutex_lock were async signal safe, this program would run forever.

    But I expect that what you would observe is that this program will either crash or deadlock after a while.

    Even if it doesn't, that still wouldn't mean that pthread_mutex_lock is safe, only that you haven't yet proved that it is unsafe.