0

I'm fuguring out how to use Futures with non-blocking event driven code (in a separate thread or not, both) but how can i end the future from a slot (~resolve the promise based on an signal) ?

QByteArray RfidCardReader::startTask(QByteArray send)
{
    if(this->busy==false) {
        this->sendFrame(send);

        QObject::connect(this, &RfidCardReader::frameReady,
        [=]() {/*this must be the startTask return*/ return this->int_read_buffer;});

    } else {
        throw 0;//Handle a queue instead
    }
}

QFuture<QByteArray> RfidCardReader::send(QByteArray passed_send)
{
    return QtConcurrent::run(QThreadPool::globalInstance(), this->startTask, passed_send);

}

basically what I want to do using only an instance is wrap a serial device (whic is sync by nature) in a queue of Futures but with only non blocking code using signals like &QIODevice::bytesWritten &QIODevice::readyRead etc... if there are better approches to the problem let me know, i would be glad to know the right way to write readable async code in Qt without blocking in separate threads

Valentino Miori
  • 477
  • 1
  • 7
  • 16
  • `this->startTask` is ill-formed, you probably mean `QtConcurrent::run(&RfidCardReader::startTask, this, passed_send)` (`QThreadPool::globalInstance()` is the used anyway) – Caleth Mar 29 '18 at 15:57
  • sure, i didn't have checked the code cause it clearly won't compile, it is not the focus, but thanks anyway, In fact it would be great to be able to use futures in the same thread also... i'm struggling to find the proper approach to this – Valentino Miori Mar 29 '18 at 16:04

1 Answers1

0

A serial device is asynchronous by nature, and using the serial port concurrently from multiple threads is undefined behavior. You can certainly resolve futures from any thread, but there's nothing in Qt that will give you a future on the same thread. Recall that a QFuture is not a class that you can sensibly instantiate. The default-constructed class is useless.

To get an idea of how to handle asynchronous serial I/O, see for example this answer.

Then you can use the undocumented <QFutureInterface> header, and create your own implementation that can wrap higher-level aspects of your protocol, i.e. commands/requests. You could then group such futures, and use a single watcher to determine when they are done.

Your approach is quite interesting in fact, and I might develop a complete example.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • great answer, great info, sync is not right, its more like sequential, i mean you must wait for an answer before making another request, the device is read or written in a single thread but other threads could make concurrent request to this thread and get back a future that is resolved as soon as it is taken on charge (after the other reqs preceeding in the queue) and the device sends the return frame or rejected on error, this is the behavior I'm loocking for, and would like to use not only for serial ports, thanks. – Valentino Miori Mar 29 '18 at 17:05
  • @ValentinoMiori That's exactly what the linked answer covers :) – Kuba hasn't forgotten Monica Mar 30 '18 at 15:13