[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