/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QFUTUREINTERFACE_P_H #define QFUTUREINTERFACE_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QFutureCallOutEvent : public QEvent { public: enum CallOutType { Started, Finished, Canceled, Paused, Resumed, Progress, ProgressRange, ResultsReady }; QFutureCallOutEvent() : QEvent(QEvent::FutureCallOut), callOutType(CallOutType(0)), index1(-1), index2(-1) { } explicit QFutureCallOutEvent(CallOutType callOutType, int index1 = -1) : QEvent(QEvent::FutureCallOut), callOutType(callOutType), index1(index1), index2(-1) { } QFutureCallOutEvent(CallOutType callOutType, int index1, int index2) : QEvent(QEvent::FutureCallOut), callOutType(callOutType), index1(index1), index2(index2) { } QFutureCallOutEvent(CallOutType callOutType, int index1, const QString &text) : QEvent(QEvent::FutureCallOut), callOutType(callOutType), index1(index1), index2(-1), text(text) { } CallOutType callOutType; int index1; int index2; QString text; QFutureCallOutEvent *clone() const { return new QFutureCallOutEvent(callOutType, index1, index2, text); } private: QFutureCallOutEvent(CallOutType callOutType, int index1, int index2, const QString &text) : QEvent(QEvent::FutureCallOut), callOutType(callOutType), index1(index1), index2(index2), text(text) { } }; class QFutureCallOutInterface { public: virtual ~QFutureCallOutInterface() {} virtual void postCallOutEvent(const QFutureCallOutEvent &) = 0; virtual void callOutInterfaceDisconnected() = 0; }; class QFutureInterfaceBasePrivate { public: QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState); // When the last QFuture reference is removed, we need to make // sure that data stored in the ResultStore is cleaned out. // Since QFutureInterfaceBasePrivate can be shared between QFuture // and QFuture objects, we use a separate ref. counter // to keep track of QFuture objects. class RefCount { public: inline RefCount(int r = 0, int rt = 0) : m_refCount(r), m_refCountT(rt) {} // Default ref counter for QFIBP inline bool ref() { return m_refCount.ref(); } inline bool deref() { return m_refCount.deref(); } inline int load() const { return m_refCount.load(); } // Ref counter for type T inline bool refT() { return m_refCountT.ref(); } inline bool derefT() { return m_refCountT.deref(); } inline int loadT() const { return m_refCountT.load(); } private: QAtomicInt m_refCount; QAtomicInt m_refCountT; }; // T: accessed from executing thread // Q: accessed from the waiting/querying thread RefCount refCount; mutable QMutex m_mutex; QWaitCondition waitCondition; QList outputConnections; int m_progressValue; // TQ int m_progressMinimum; // TQ int m_progressMaximum; // TQ QAtomicInt state; // reads and writes can happen unprotected, both must be atomic QElapsedTimer progressTime; QWaitCondition pausedWaitCondition; QtPrivate::ResultStoreBase m_results; bool manualProgress; // only accessed from executing thread int m_expectedResultCount; QtPrivate::ExceptionStore m_exceptionStore; QString m_progressText; QRunnable *runnable; QThreadPool *m_pool; inline QThreadPool *pool() const { return m_pool ? m_pool : QThreadPool::globalInstance(); } // Internal functions that does not change the mutex state. // The mutex must be locked when calling these. int internal_resultCount() const; bool internal_isResultReadyAt(int index) const; bool internal_waitForNextResult(); bool internal_updateProgress(int progress, const QString &progressText = QString()); void internal_setThrottled(bool enable); void sendCallOut(const QFutureCallOutEvent &callOut); void sendCallOuts(const QFutureCallOutEvent &callOut1, const QFutureCallOutEvent &callOut2); void connectOutputInterface(QFutureCallOutInterface *iface); void disconnectOutputInterface(QFutureCallOutInterface *iface); void setState(QFutureInterfaceBase::State state); }; QT_END_NAMESPACE #endif