[Interest] Calling QT Class method from pthread thread
Gonzalo Aguilar Delgado
gaguilar at aguilardelgado.com
Wed Oct 4 17:32:03 CEST 2017
Hello,
I moved from that solution that's not working to another approach I've
used in other projects. It's like the pooled mechanism used by Qt to
send signals. I've created a Queue with QQueue.
The callback only has to put a new message to be processed in the queue.
The class that was previously MQMessageManager is now a thread that
takes elements from the queue to process them.
What's my surprise? It also failed!!!! Appart from the fact I didn't
mutexed the access...
The inferior stopped because it received a signal from the operating system.
Signal name :
SIGSEGV
Signal meaning :
Segmentation fault
Here inside QList...
// This violates pointer aliasing rules, but it is known to be safe (and
silent)// in unoptimized GCC builds (-fno-strict-aliasing). The other
compilers which// set the same define are assumed to be safe.else
*reinterpret_cast<T*>(n) = t;
I'm starting to thing the election of this framework was not a good
idea. C'mon...
On 04/10/17 13:08, Gonzalo Aguilar Delgado 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
> 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/e54074e6/attachment.html>
More information about the Interest
mailing list