1
Summary
-----------
1. In main() am going for pthread_cond_wait().
2. In signal handler() am waking main() using pthread_cond_signal().
3. But main() is not coming out from pthread_cond_wait().

What is wrong here? help me out.

#include <stdio.h>  
myclass *myObj = NULL;

In main I am trying to wait for a signal:

int main()
{
    myObj = new myclass;    
    /* do something */
    myobj->gotoWait(); <=== Wait blocked for ever.
    /* do clean up here */
    return 0;
}

Signal handler sending a signal to main thread:

static void signalHandler(int sig, siginfo_t *siginfo, void *context)
{
    myObj->wakeFromWait();
}

Actual class implementing the waiting for and sending of signals.

What is wrong here?

myclass::gotoWait()
{
    pthread_mutex_lock(&mtx);
    pthread_cond_wait(&cnd, &mtx);
    pthread_mutex_unlock(&mtx);
} 
myclass::wakeFromWait()
{
    pthread_mutex_lock(&mtx);
    pthread_cond_signal(&cnd, &mtx);
    pthread_mutex_unlock(&mtx);
}
tsn
  • 838
  • 9
  • 20
rameshrgtvl
  • 243
  • 2
  • 16
  • _What is wrong here?_ ① You don't give us an [MCVE](http://stackoverflow.com/help/mcve). ② You are using a condition variable without a predicate, which is likely incorrect for any non-trivial application even absent spurious wakeups. ③ You wait for a condition variable without anticipating [spurious wakeups](http://stackoverflow.com/q/1050592/132382). ④ You invoke `pthread_cond_wait` incorrectly — how did this compile? ⑤ You do unsafe things in a signal handler. – pilcrow Jun 17 '15 at 14:43

2 Answers2

4

In Signal handler there are only a very limited number of syscalls allowed.

see man 7 signal

http://man7.org/linux/man-pages/man7/signal.7.html

My Suggestion is, to be on the safe side, the so called "self pipe trick". http://man7.org/tlpi/code/online/diff/altio/self_pipe.c.html

You could start a thread which runs a select Loop on the self pipe and call your appropiate handler.

What is wrong in your code? You are locking a mutex inside the Signal handler

EDIT: Here there is a guide for signals http://beej.us/guide/bgipc/output/html/multipage/signals.html

schorsch_76
  • 794
  • 5
  • 19
2

Perhaps you could use sigprocmask() to make sure a given signal will not arrives at a specific point in your code, and then the signal handler can't be executed in that point.
For example:
* The code below was based from this James Sullivan's article

Functions to lock/unlock (maybe) the about-to-arrive signal:

void signal_lock (sigset_t *save) {
    sigset_t set;

    sigfillset(&set); /* fill `set` with __all__ signals */
    sigprocmask(SIG_BLOCK, &set, save); /* no more signals :-)  */
}

void signal_unlock (sigset_t *save) {
    sigprocmask(SIG_SETMASK, save, NULL); /* enable again */
}

After a call to signal_lock() ...

sigset_t tmp;

signal_lock(&tmp); /* we locked all signals --
                    * no signal will arrives until signal_unlock() */
pthread_mutex_lock(<pthread_mutex_t*>);
/* do your stuff */
pthread_mutex_unlock(<pthread_mutex_t*>);
signal_unlock(&tmp); /* unlock signals --
                      * only signals allowed before signal_lock()
                      * may arrive */

I recommend you to read thoroughly this amazing article by James Sullivan, it explains better the things :-)

psqli
  • 588
  • 6
  • 11