Skip to content

Instantly share code, notes, and snippets.

@vprus
Created October 29, 2015 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vprus/3a7bea25e4c0a0e4222d to your computer and use it in GitHub Desktop.
Save vprus/3a7bea25e4c0a0e4222d to your computer and use it in GitHub Desktop.
Qt + boost::future experiment
#include <QCoreApplication>
#include <QTimer>
#include <QDebug>
#include <QThread>
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_FUTURE 1
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION 1
#define BOOST_THREAD_PROVIDES_EXECUTORS 1
#define BOOST_ALL_NO_LIB
#pragma comment(lib, "libboost_thread-vc120-mt-gd-1_60.lib")
#pragma comment(lib, "libboost_system-vc120-mt-gd-1_60.lib")
#define _CPPUNWIND 1
#undef BOOST_NO_EXCEPTIONS
#include <boost/thread/future.hpp>
#include <boost/system/error_code.hpp>
using namespace boost;
class Executor : public QObject
{
public:
template<class F>
void submit(F &w)
{
qDebug() << "Executor called in thread " << QThread::currentThread();
if (QThread::currentThread() == thread()) {
w();
} else {
QTimer::singleShot(0, this, [w]() mutable {
w();
});
}
}
void close() {
}
bool closed() {
return false;
}
bool try_executing_one() {
Q_ASSERT("not implemented");
return true;
}
template<class P>
void reshedule_until(const P &p) {
Q_ASSERT("not implemented");
}
};
class Task : public QObject
{
public:
Task()
{
boost::executor_ptr_type e(new boost::executor_adaptor<Executor>());
p.set_executor(e);
}
boost::future<int> run()
{
qDebug() << "Thread affinity: " << thread();
QTimer::singleShot(1000, this, [this] {
qDebug() << "Value set in thread " << QThread::currentThread();
p.set_value(10);
});
return p.get_future();
}
private:
boost::promise<int> p;
};
class WorkerThread : public QThread
{
public:
boost::future<int> doSomething()
{
Task *t = new Task();
t->moveToThread(this);
return t->run();
// Leak t for this test code
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThread *mainThread = QThread::currentThread();
qDebug() << "Starting up, main thread " << QThread::currentThread();
WorkerThread workerThread;
boost::future<int> f = workerThread.doSomething();
f.then([mainThread](future<int> x) {
qDebug() << "Got future value " << x.get() << " in thread " << QThread::currentThread();
});
workerThread.start();
return a.exec();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment