I have a such a requirement that:- 1) There are two class, say Wrapper and Wrapper2. 2) Wrapper2 contains reference object of class Wrapper. 3) A thread will write data to a variable of class Wrapper which should be essentially be calling a member function of Wrapper. 4) Another thread can read and write data to class member of Wrapper and this thread essentially be called through Wrapper2.
Based on some answers on older question on Stackoverflow, i created an example code to check why my production code is failing and i am not able to figure out the problem. As soon as thread2 is created it receives SIGSEG signals. Code is below:-
#include <thread>
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <wait.h>
#include <string.h>
pthread_mutex_t mt1;
void thread_signal(int signum)
{
pthread_exit(0);
}
void sig_func(int sig)
{
write(1, "Caught signal 11\n", 17);
std::cout<<"Caught signal :"<<sig<<std::endl;
signal(SIGSEGV,sig_func);
thread_signal(sig);
}
class Wrapper {
public:
Wrapper():i(10)
{
std::cout<<"Wrapper Constructor Called. "<<this<<" \n";
}
~Wrapper()
{
std::cout<<"Wrapper Destructor Called. "<<this<<"\n";
}
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
void setI(int i)
{
pthread_mutex_lock(&mt1);
this->i=i;
std::cout<<"set: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
}
int getI()
{
pthread_mutex_lock(&mt1);
std::cout<<"get: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
return 0;
}
int i;
};
class Wrapper2
{
public:
Wrapper2(Wrapper & wp):wp2(wp)
{
std::cout<<"Wrapper2 Constructor Called. "<<this<<" \n";
}
~Wrapper2()
{
std::cout<<"Wrapper2 Destructor Called. "<<this<<" \n";
}
Wrapper & wp2;
};
struct ThreadWrapper {
Wrapper & wr1;
Wrapper2 & wr2;
ThreadWrapper( Wrapper & wr1,Wrapper2& wr2):
wr1(wr1),wr2(wr2)
{
}
};
extern "C" void* wrapper1Fun ( void* wr1)
{
std::auto_ptr< Wrapper > wrp1 ( static_cast< Wrapper* >( wr1 ) );
std::cout<<"Thread 1 created. \n";
while(1)
{
wrp1->setI(rand()%100);
usleep(50);
}
return 0;
}
extern "C" void* wrapper2Fun ( void* wr2)
{
std::auto_ptr< Wrapper2 > wrp2 ( static_cast< Wrapper2* >( wr2 ) );
std::cout<<"Thread 2 created. \n";
while(1)
{
wrp2->wp2.getI();
usleep(50);
}
return 0;
}
int main(int argc, char **argv) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = thread_signal;
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, 0);
bool mainRunning= true;
Wrapper w;
Wrapper2 w1(w);
sleep(1);
ThreadWrapper * myWrap = new ThreadWrapper(w,w1);
sleep(1);
pthread_t pt1;
pthread_t pt2;
pthread_attr_t attr;
signal(SIGSEGV,sig_func); // Register signal handler before going multithread
pthread_attr_init(&attr);
int i = pthread_create(&pt1, NULL,wrapper1Fun, myWrap);
std::cout<<"First thread status "<<i<<std::endl;
sleep(1);
int j = pthread_create(&pt2, &attr,wrapper2Fun, myWrap);
std::cout<<"Second thread status "<<j<<std::endl;
sleep(1);
while(1);
fprintf(stderr, "kill thread\n");
//pthread_kill(pt1, SIGTERM);
fprintf(stderr, "join thread\n");
pthread_join(pt1, NULL);
pthread_join(pt1, NULL);
return 0;
}
std::auto_ptr?