0

I have created a child process where I am handling a SIGTERM sent from the parent process. In the child process I am waiting on a condition_variable cv inside a new thread waitingForWork(). cv is set by the SIGTERM signal handler inside stopTheWait() function.

For some reason the stopTheWait() function cannot acquire the lock and waitingForWork() waits for ever and doTheCleanUp() is never called.

Finally the Parent process closes.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable


std::mutex mtx;
std::condition_variable cv;

void stopTheWait(){
    printf("[CHILD] Stopping the wait.. \n\n");
    std::lock_guard<std::mutex> lck(mtx);
    cv.notify_all();
}

void signal_callback_handler(int signum)
{
   printf("[CHILD] Caught signal, trying to stop the wait... %d\n\n",signum);
   stopTheWait();
}

void doTheCleanUp()/* is never called*/ {
    printf("[CHILD] clean up... \n\n");
}

void waitingForWork(){
    printf("[CHILD] wait for ever... \n\n");

    std::unique_lock<std::mutex> lck(mtx);
    cv.wait(lck);
    doTheCleanUp();
    printf("[CHILD] clean Up Done, now end wait... \n\n");
    exit(0);
}


int main()
{
    printf("[PARENT] in parent...\n");
    int pid;
   if ((pid = fork()) < 0) { 
        perror("fork"); 
        exit(1); 
    } 
    
   if (pid == 0) 
    { /* child */
        signal(SIGTERM, signal_callback_handler);
        std::unique_lock<std::mutex> lck(mtx);

        std::thread t1(waitingForWork);
        t1.join();
        
        waitingForWork();
        printf("[CHILD] wait is over...\n\n");
    } 

    else /* parent */
    { /* pid hold id of child */

        sleep(3); /* pause for 3 secs */
        printf("[PARENT] sending SIGTERM\n\n"); 
        kill(pid, SIGTERM); 
        sleep(3);
    } 

   printf("[PARENT] exiting parent...\n");
   sleep(1);
   
   return 0;
}

I see below print.

enter image description here

cigien
  • 57,834
  • 11
  • 73
  • 112
Soumyajit Roy
  • 463
  • 2
  • 8
  • 17

1 Answers1

0

[support.signal]/3 An evaluation is signal-safe unless it includes one of the following:

(3.1) — a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe.
...

A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.

There's very little one can safely do in a signal handler. printf, mutex and condition variable operations are right out.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85