[Interest] Calling QT Class method from pthread thread
Gonzalo Aguilar Delgado
gaguilar at aguilardelgado.com
Wed Oct 4 15:06:02 CEST 2017
Hello,
Ok. But what does it has to do with the emit signal? It should not crash
even if the signal is emitted from worker thread.
I find not useful this without an explanation on how to make it work and
why. But thank you for your response.
On 04/10/17 14:12, Harish Surana wrote:
> From Qt Documentation
> http://doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-thread
>
> "As mentioned, each program has one thread when it is started. This
> thread is called the "main thread" (also known as the "GUI thread" in
> Qt applications). The Qt GUI must run in this thread. All widgets and
> several related classes, for example QPixmap
> <http://doc.qt.io/qt-5/qpixmap.html>, don't work in secondary threads.
> A secondary thread is commonly referred to as a "worker thread"
> because it is used to offload processing work from the main thread."
>
> On Wed, Oct 4, 2017 at 1:08 PM, Gonzalo Aguilar Delgado
> <gaguilar at aguilardelgado.com <mailto:gaguilar at aguilardelgado.com>> wrote:
>
> Hello,
>
> I'm facing a problem that don't know how to tackle. I created a
> library that runs on C. It's based on callbacks and it seems to
> work in other projects well.
>
> When connecting to Qt and classes I found a couple of problems
> that now they are extending.
>
> It seems that I cannot set a callback from C directly to a class,
> so I created an intermediate static function that will wrap the
> call to the class.
>
> static gboolean callbackWrapper(SG64ZeroMQ* mq, ThriftStruct*
> message, gpointer data, GError **error) { qDebug("Message
> received"); MQMessageManager *self =
> static_cast<MQMessageManager*>(data); fflush(stdout);
> qDebug("Thread of the call %x", QThread::currentThread());
> self->processMessage(mq, message, error); return TRUE;}
>
> Nice. We get the class from the callback. Do a static cast and go
> ahead with processing. But I want to notify other class that a
> event happend, with a Signal.
>
> For completeness I include also constructor.
>
> MQMessageManager::MQMessageManager()
> :error(NULL),mqsubscriber(NULL){qDebug("Thread of the class %x",
> QThread::currentThread());}
>
> bool MQMessageManager::processMessage(SG64ZeroMQ* mq,
> ThriftStruct* message, GError **error){ mqPayload
> *payload=NULL; mqCardEvent *cardEvent = NULL; mqMessage
> *msg=NULL; QString str; g_return_val_if_fail
> (THRIFT_IS_STRUCT (message), FALSE);
> if(IS_MQ_MESSAGE(message)) msg=MQ_MESSAGE(message);
> switch(msg->type){ case MQ_MESSAGE_TYPE_COMMAND:
> puts("Received a command"); break; case
> MQ_MESSAGE_TYPE_GPS_EVENT: puts("Received a gps
> event"); break; case
> MQ_MESSAGE_TYPE_CARD_EVENT:
> if(IS_MQ_CARD_EVENT(msg->payload->card_event)){
> cardEvent = msg->payload->card_event;
> if(cardEvent!=NULL && cardEvent->atr!=NULL){
> QByteArray array((char *)cardEvent->atr->data, (int)
> cardEvent->atr->len); QString atr =
> QString(array.toHex()); qDebug("ATR found of size
> %d, %s", cardEvent->atr->len,
> atr.toLatin1().data());* emit
> cardValidationSuccess();**** qDebug("Emitted valid
> signal");* } } break;
> default: printf("Message of type %i cannot be managed\n",
> msg->type); break; } return TRUE;}
>
> Of course I did the typical connect signals functions. Done in the
> MainWindow.cpp class. After object creation and all the stuff.
>
> qDebug("Thread of the connect %x",
> QThread::currentThread());
> if(!QObject::connect(mqMessageManager,
> SIGNAL(cardValidationSuccess()), this,
> SLOT(displayValid()),Qt::QueuedConnection)){ qDebug("Cannot
> connect signal"); } QObject::connect(mqMessageManager,
> SIGNAL(valid(QString)), this, SLOT(displayValid(QString)),
> Qt::BlockingQueuedConnection);
>
> Well, when the emit is called the system blows up!
>
> My investigations tells me that since the emit is called from the
> callback thread and the class was created in another thread
> there's a problem there that avoids the system to correctly
> function. The problem is that everyone tells me that signal
> emission doesn't has anything to do with thread affinity. I don't
> think so with the proof in my hand.
>
> When you run the code the log is shown like this:
>
> Thread of the class 557845a0
>
> Starting ticketing
>
> Thread of the connect 557845a0
>
> Connecting localhost
>
> Connected to server
>
> Message received
>
> Thread of the call c00024f0
>
> ATR ...
>
> ---Crash on emit---
>
> The question is. Is there any way to run self->processMessage(mq,
> message, error); On the same thread the class was defined
> 0x557845a0 instead of the calling thread 0xc00024f0?
>
> I defined process message like a slot. But if I use invokeMethod
> it also crash when calling it. I suppose because the same issue.
> moveToThread also doesn't work and it fails, I suppose because the
> same problem.
>
> The root of the issue to me is that a pthread doesn't have all the
> information that QT injects into the software and it makes
> everything run there to blow up when using QT mechanism. Since the
> support is not enable on that thread.
>
> Any help on this?
>
> Best regards,
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org <mailto:Interest at qt-project.org>
> http://lists.qt-project.org/mailman/listinfo/interest
> <http://lists.qt-project.org/mailman/listinfo/interest>
>
>
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171004/e5a9ad81/attachment.html>
More information about the Interest
mailing list