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 <gagui...@aguilardelgado.com <mailto:gagui...@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@qt-project.org <mailto:Interest@qt-project.org>
    http://lists.qt-project.org/mailman/listinfo/interest
    <http://lists.qt-project.org/mailman/listinfo/interest>




_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to