PDA

View Full Version : Destructor, Inheritance and Threads



cafu
28th October 2009, 14:19
HI everybody,

I have a small question. but first i want to say, that perhaps this is no so related to Qt.
But perhaps( at least i hope) it helpfull in general.

Here is some code to help to undesrtand my problem:



/***/
class WorkerThread;

class Father: public QObject
{
public:
Father();
~Father();
void doSome();
protected:
virtual qint32 function()=0;
virtual void work();
WorkerThread* worker;
friend class WorkerThread;
bool running;
bool working;
virtual void stop();
};
Father::Father()
{
working=false;
running=true;
worker=new WorkerThread(this);
worker->start();
}
Father::~Father()
{
if(worker)
{
if(worker->IsRunning())
{
stop();
}
if (QThread::currentThread() != worker)
{
while (!worker->wait(2000))
{
}
}
delete worker;
}
}
void Father::doSome()
{
working=true;
}
void Father::stop()
{
running=false;
}
void Father::work()
{
//other stuff
qint32 a=function();
}
/***/
classs WorkerThread: public QThread
{
public:
WorkerThread(Father *d);
protected:
void run();
private:
Father* friend;
};
WorkerThread(Father *d)
{
friend=d;
}
void WorkerThread::run()
{
while(friend->running)
{
if(friend->working)
{
friend->working=false;
friend->work();
}
}
}
/***/
class Child(): public Father
{
public:
Child();
~ Child();
protected:
virtual qint32 function();
};
Child::Child():
Father()
{
}
Child::~Child()
{
//empty
}
qint32 Child::function()
{
//some work;
}
/***/
class Window:public QWidget
{
public:
Window(QWidget*);
~Window();
private:
Child* pointer;
private slots:
void on_button1_clicked();
};
Window(QWidget* parent):
QWidget(parent)
{
pointer = new Child();
}
Window::~Window()
{
if(pointer)
{
delete pointer;
}
}
void Window::on_button1_clicked()
{
pointer->doSome();
}
/***/


i have also some mutex but i think is no need to show then here

destructor call are done in this order
dtr Window;
dtr Child;
dtr Father; which also call the dtr of worker.

the problem appear when the worker is inside "work" and the destructor is called, then it reaches the called of function "function" (that is virtual and implemented in childs) and it crash. i have found (or better i think) that the function seems to dont exist any longer since the dtr of Child have been already called. So my solution was to called the the stop of the thread in the child. but i don like this solution since i have several child and i wiil to reimplemt (copy and paste) in all of then. Is this a normal behavior? or someone have a better idea?

PS: This is not a running code just to explain a bit what occur to me

Ginsengelf
28th October 2009, 14:31
Hi,

if (QThread::currentThread() != worker)

I think this cannot work because if the program checks this condition it is per definitionem not in worker thread but in the thread where Father lives.

Ginsengelf

cafu
28th October 2009, 14:41
well this should not be false, but a extra preacaution