[Interest] Calling QT Class method from pthread thread

Gonzalo Aguilar Delgado gaguilar at aguilardelgado.com
Wed Oct 4 13:08:02 CEST 2017


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,

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171004/840cb02a/attachment.html>


More information about the Interest mailing list