I want to make a control loop interface.
It has should_stop()
method to check if loop should break or continue.
It does listen to SIGINT
signal(Ctrl+C) and after it gets the signal should_stop()
method returns True.
Now it seems like this interface is working.
But I'm not sure this interface is thread-safe.
LoopInterface.h file
#include "signal.h"
#include "pthread.h"
#define LOCK(mutex) pthread_mutex_lock(&mutex)
#define UNLOCK(mutex) pthread_mutex_unlock(&mutex)
class LoopInterface {
public:
LoopInterface(){
LOCK(_lock_is_signal_registered);
bool temp = _is_signal_registered;
UNLOCK(_lock_is_signal_registered);
if(!temp)
{
register_signal();
}
}
bool should_stop()
{
LOCK(_lock_should_stop);
bool temp = _should_stop;
UNLOCK(_lock_should_stop);
return _should_stop;
}
private:
static void register_signal()
{
LOCK(_lock_is_signal_registered);
_is_signal_registered = true;
UNLOCK(_lock_is_signal_registered);
signal(SIGINT, &LoopInterface::signal_handler);
}
static void signal_handler(int sig){
LOCK(_lock_should_stop);
_should_stop = true;
UNLOCK(_lock_should_stop);
}
static bool _should_stop;
static bool _is_signal_registered;
static pthread_mutex_t _lock_should_stop, _lock_is_signal_registered;
};
LoopInterface.cpp file
#include "LoopInterface.h"
bool LoopInterface::_should_stop = false;
bool LoopInterface::_is_signal_registered = false;
pthread_mutex_t LoopInterface::_lock_should_stop;
pthread_mutex_t LoopInterface::_lock_is_signal_registered;
And this is how it is used.
/************Threads*************/
#include "LoopInterface.h"
class A : public LoopInterface{
};
void threadX(){
A a;
while(!a.should_stop()){
//do something...
}
}
Can you tell me this interface would work thread-safely? or not?
If not, what is the problem?
Additional Problem
There is one more problem on my synchronized code.
Deadlock occurs quite frequently because of calling pthread_mutex_lock
in signal_handler
while should_stop
method is locking the same mutex
.
And I found an article stating that thread-related functions should not called in signal handler.
I think I should find another way to synchronize my member variables.