qt-helpers.hpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #pragma once
  2. #include <functional>
  3. #include <QFuture>
  4. #include <QtGlobal>
  5. template<typename T> struct FutureHolder {
  6. std::function<void()> cancelAll;
  7. QFuture<T> future;
  8. };
  9. QFuture<void> CreateFuture();
  10. template<typename T> inline QFuture<T> PreventFutureDeadlock(QFuture<T> future)
  11. {
  12. /*
  13. * QFutures deadlock if there are continuations on the same thread that
  14. * need to wait for the previous continuation to finish, see
  15. * https://github.com/qt/qtbase/commit/59e21a536f7f81625216dc7a621e7be59919da33
  16. *
  17. * related bugs:
  18. * https://bugreports.qt.io/browse/QTBUG-119406
  19. * https://bugreports.qt.io/browse/QTBUG-119103
  20. * https://bugreports.qt.io/browse/QTBUG-117918
  21. * https://bugreports.qt.io/browse/QTBUG-119579
  22. * https://bugreports.qt.io/browse/QTBUG-119810
  23. * @RytoEX's summary:
  24. * QTBUG-119406 and QTBUG-119103 affect Qt 6.6.0 and are fixed in Qt 6.6.2 and 6.7.0+.
  25. * QTBUG-119579 and QTBUG-119810 affect Qt 6.6.1 and are fixed in Qt 6.6.2 and 6.7.0+.
  26. * QTBUG-117918 is the only strange one that seems to possibly affect all Qt 6.x versions
  27. * until 6.6.2, but only in Debug builds.
  28. *
  29. * To fix this, move relevant QFutures to another thread before resuming
  30. * on main thread for affected Qt versions
  31. */
  32. #if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) && \
  33. (QT_VERSION < QT_VERSION_CHECK(6, 6, 2))
  34. if (future.isFinished()) {
  35. return future;
  36. }
  37. return future.then(QtFuture::Launch::Async, [](T val) { return val; });
  38. #else
  39. return future;
  40. #endif
  41. }