Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, January 2008
QThread, QPlugin, and Factories


Message 1 in thread

Qt!

I use QPlugin implemented as Factories so I can create as many instances as
needed of the loaded plugin. The instances should be created in a different
QThread than the thread in which the Factory lifes in.

A seg fault occurs right after creating the instance. (In the source code
indicated with an arrow <---). I think that's because the createBP is
called from a different thread than the thread where the Factory lifes in.
I do not understand why. And how to solve this.

A possible solution (but not tested yet):
Put the Factory in a QThread and push it temporarily into the Worker Thread.
There the instance of the QPlugin is created. Then the Factory Thread is
pushed back to the main thread. I have not tested this. That's some work to
do. And I do not know if it will work. Any suggestions?

For the interessed people here is the source code:



************************************
** WorkerThread
************************************
class WorkerThread : public QThread
{
        Q_OBJECT
public slots:
        void run();
private:
        Worker * m_worker;
};

void WorkerThread::run( )
{
        m_worker = new Worker();
        m_worker->start();
}



************************************
** Worker
************************************
class Worker : public QObject
{
        Q_OBJECT
public slots:
        void start();
};


void Worker::start()
{
        BP * bp = (...)->createBP();     <------- SEG FAULT
        connect(bp,SIGNAL(outData(Data)),parent,SLOT(inData(Data)));
}


************************************
** BP
************************************
class BP: public QObject
{
        Q_OBJECT
public slots:
        virtual void inData( Data in ) = 0;
signals:
        virtual void outData( Data out ) = 0;
};



************************************
** BPFactory
************************************
class BPFactory
{
public:
        virtual ~BPFactory() {}
        virtual BP * createBP() = 0;
};
Q_DECLARE_INTERFACE(BPFactory,"BPFactory/1.0")



************************************
** A concrete BP
************************************
class Gemi: public BP
{
        Q_OBJECT
public slots:
        virtual void inData( Data in );
signals:
        virtual void outData( Data out );
};


************************************
** A concrete BP Factory
************************************
class GemiFactory: public QObject, public BPFactory
{
        Q_OBJECT
        Q_INTERFACES(BPFactory)
public:
        virtual BP * createBP();
};


BP * GemiFactory::createBP()
{
        BP * bp = new Gemi();
        return bp;
}
Q_EXPORT_PLUGIN2(gemi, GemiFactory)




--
 [ signature omitted ] 

Message 2 in thread

On Jan 19, 2008 3:53 PM, Frank <frank.t.winter@xxxxxxxxx> wrote:
> void Worker::start()
> {
>         BP * bp = (...)->createBP();     <------- SEG FAULT
>         connect(bp,SIGNAL(outData(Data)),parent,SLOT(inData(Data)));
> }

Small questions.

Where does (...) come from? What's the value of (...)? What happens
when you run through a debugger?


-- 
 [ signature omitted ] 

Message 3 in thread

Robin Helgelin wrote:

> On Jan 19, 2008 3:53 PM, Frank <frank.t.winter@xxxxxxxxx> wrote:
>> void Worker::start()
>> {
>>         BP * bp = (...)->createBP();     <------- SEG FAULT
>>         connect(bp,SIGNAL(outData(Data)),parent,SLOT(inData(Data)));
>> }
> 
> Small questions.
> 
> Where does (...) come from? What's the value of (...)? What happens
> when you run through a debugger?
> 
> 

Calling createBP() is not the problem. Returning from it is the problem. I
use debug output in createBP(). Besides (...) is a pointer to BPFactory
that is passed when Worker is constructed.

Like this:

void Worker::start(BPFactory * mbf)
{
        BP * bp = mbf->createBP();     <------- SEG FAULT, when returning
        connect(bp,SIGNAL(outData(Data)),parent,SLOT(inData(Data)));
}



--
 [ signature omitted ] 

Message 4 in thread

Hi,

> A seg fault occurs right after creating the instance. (In the source code
> indicated with an arrow <---). I think that's because the createBP is
> called from a different thread than the thread where the Factory lifes in.
> I do not understand why. And how to solve this.

What if you try to reproduce the problem with a small, complete, compilable 
example? You coudl strip down your code until it doesn't crash. For example 
you could change:
	BP * bp = (...)->createBP();
into:
	BP * bp = new Gemi();
and also get rid of the plugin stuff.

Also have you run your code in Valgrind or some similar memory debugger?

--
 [ signature omitted ] 

Message 5 in thread

Hi,

I have two ideas for you to try out, but it's impossible to say if they 
actually fix the problem or not. My best guess would be that you're chasing 
the symptom instead of the problem, meaning that I would think valgrind (or 
any other memory debugger) will show you there's an issue in the called 
method.

However, two issues could be problematic here. If the factory method 
instantiates any gui classes, it's going to break somehow (might be a crash, 
might not), because gui objects must be in the main thread. Another idea 
could be that you might be instantiating qobject derived classes with a 
parent from another thread.

I hope this helps,

Bo.

On lørdag den 19. Januar 2008, Frank wrote:
> Qt!
>
> I use QPlugin implemented as Factories so I can create as many instances as
> needed of the loaded plugin. The instances should be created in a different
> QThread than the thread in which the Factory lifes in.
>
> A seg fault occurs right after creating the instance. (In the source code
> indicated with an arrow <---). I think that's because the createBP is
> called from a different thread than the thread where the Factory lifes in.
> I do not understand why. And how to solve this.
>
> A possible solution (but not tested yet):
> Put the Factory in a QThread and push it temporarily into the Worker
> Thread. There the instance of the QPlugin is created. Then the Factory
> Thread is pushed back to the main thread. I have not tested this. That's
> some work to do. And I do not know if it will work. Any suggestions?
>
> For the interessed people here is the source code:
>
>
>
> ************************************
> ** WorkerThread
> ************************************
> class WorkerThread : public QThread
> {
>         Q_OBJECT
> public slots:
>         void run();
> private:
>         Worker * m_worker;
> };
>
> void WorkerThread::run( )
> {
>         m_worker = new Worker();
>         m_worker->start();
> }
>
>
>
> ************************************
> ** Worker
> ************************************
> class Worker : public QObject
> {
>         Q_OBJECT
> public slots:
>         void start();
> };
>
>
> void Worker::start()
> {
>         BP * bp = (...)->createBP();     <------- SEG FAULT
>         connect(bp,SIGNAL(outData(Data)),parent,SLOT(inData(Data)));
> }
>
>
> ************************************
> ** BP
> ************************************
> class BP: public QObject
> {
>         Q_OBJECT
> public slots:
>         virtual void inData( Data in ) = 0;
> signals:
>         virtual void outData( Data out ) = 0;
> };
>
>
>
> ************************************
> ** BPFactory
> ************************************
> class BPFactory
> {
> public:
>         virtual ~BPFactory() {}
>         virtual BP * createBP() = 0;
> };
> Q_DECLARE_INTERFACE(BPFactory,"BPFactory/1.0")
>
>
>
> ************************************
> ** A concrete BP
> ************************************
> class Gemi: public BP
> {
>         Q_OBJECT
> public slots:
>         virtual void inData( Data in );
> signals:
>         virtual void outData( Data out );
> };
>
>
> ************************************
> ** A concrete BP Factory
> ************************************
> class GemiFactory: public QObject, public BPFactory
> {
>         Q_OBJECT
>         Q_INTERFACES(BPFactory)
> public:
>         virtual BP * createBP();
> };
>
>
> BP * GemiFactory::createBP()
> {
>         BP * bp = new Gemi();
>         return bp;
> }
> Q_EXPORT_PLUGIN2(gemi, GemiFactory)
>
>
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/



-- 
 [ signature omitted ]