0

I'm attempting to run a function concurrently using QtConcurrent but I'm running into issues with one of the arguments.

As a precursor, lets say I have the following classes and "interfaces":

class DataMessage : public QObject {
    Q_OBJECT
    // ... fields and methods
};

class ITimeStampInfo {
    public:
        virtual QDateTime timestamp() const = 0;
};
Q_DECLARE_INTERFACE(ITimeStampInfo, "My.TimeStampInfo/1.0")

class IDataLengthInfo {
    public:
        virtual int dataLength() const = 0;
};
Q_DECLARE_INTERFACE(IDataLengthInfo, "My.IDataLengthInfo/1.0")

class DataMessage1 : public DataMessage, public ITimeStampInfo {
    Q_OBJECT
    Q_INTERFACES(ITimeStampInfo)
    // other fields, etc
    QDateTime timestamp() const;
};

class DataMessage2 : public DataMessage, public IDataLengthInfo {
    Q_OBJECT
    Q_INTERFACES(IDataLengthInfo)
    // other fields
    int dataLength() const;
};

And a class function called processDataMessages:

void MyClass::processDataMessages(DataMessage *msg) {
    // Previous to this function being called, concrete `DataMessage`
    // instances are created and passed by pointer into this function

    // Determine the data in the message
    IDataLengthInfo *dl = qobject_cast<IDataLengthInfo*>(msg);

    if (dl) {
        qDebug() << "Got a message with IDataLengthInfo";
    }

    ITimeStampInfo *ts = qobject_cast<ITimeStampInfo*>(msg);

    if (ts) {
        qDebug() << "Got a message with ITimeStampInfo";
    }

    // etc
}

This processDataMessages is called in a slot. During normal operation, this function works perfectly and the qDebug() statements execute as expected as the pointer is correct - for example, inspecting the pointer type in the debugger results in a DataMessage1 type, for instance

I now want to run this function asynchronously as potentially, there may be a bit of work to do. If I try to execute this function using QtConcurrent::run from within the slot as follows:

void MyClass::dataReceived(DataMessage *msg) {
    // this->processDataMessages(msg);
    QtConcurrent::run(this, &MyClass::processDataMessages, msg);
}

Now when I break on the first qobject_cast line in the processDataMessages function, I can see that the msg pointer is of type DataMessage and not any of the DataMessage1 or DataMessage2 types.

Something is being lost during the operation of QtConcurrent::run and its probably something dumb I've missed.

weblar83
  • 681
  • 11
  • 32

1 Answers1

0

Ok, so as it turns out, the following code works:

QFuture<void> f = QtConcurrent::run(this, &MyClass::processDataMessages, msg);
// Wait for the function to finish
f.waitForFinished();

Doesn't really seem any different to the original but something in the return value may be maintaining state??

weblar83
  • 681
  • 11
  • 32
  • I expect that `msg` is destructed in the function that calls `dataReceived`. By blocking your main thread using `waitForFinished`, you will not take advantage of the asynchronous behaviour. – m7913d Sep 21 '17 at 15:40
  • Good point, it hadn't actually occurred to me that `waitForFinished` would block the main thread. Hmmm... – weblar83 Sep 21 '17 at 15:49