File indexing completed on 2025-03-09 03:56:11

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2011-12-28
0007  * Description : Low level threads management for batch processing on multi-core
0008  *
0009  * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText:      2014 by Veaceslav Munteanu <veaceslav dot munteanu90 at gmail dot com>
0011  * SPDX-FileCopyrightText: 2011-2012 by Janardhan Reddy <annapareddyjanardhanreddy at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_ACTION_THREAD_BASE_H
0018 #define DIGIKAM_ACTION_THREAD_BASE_H
0019 
0020 // Qt includes
0021 
0022 #include <QHash>
0023 #include <QObject>
0024 #include <QThread>
0025 #include <QRunnable>
0026 #include <QElapsedTimer>
0027 
0028 // Local includes
0029 
0030 #include "digikam_export.h"
0031 
0032 namespace Digikam
0033 {
0034 
0035 class DIGIKAM_EXPORT ActionJob : public QObject,
0036                                  public QRunnable
0037 {
0038     Q_OBJECT
0039 
0040 public:
0041 
0042     /**
0043      * Constructor which delegate deletion of QRunnable instance to ActionThreadBase, not QThreadPool.
0044      */
0045     explicit ActionJob(QObject* const parent = nullptr);
0046 
0047     /**
0048      * Re-implement destructor in you implementation. Don't forget to cancel job.
0049      */
0050     ~ActionJob() override;
0051 
0052 Q_SIGNALS:
0053 
0054     /**
0055      * Use this signal in your implementation to inform ActionThreadBase manager that job is started
0056      */
0057     void signalStarted();
0058 
0059     /**
0060      * Use this signal in your implementation to inform ActionThreadBase manager the job progress
0061      */
0062     void signalProgress(int);
0063 
0064     /**
0065      * Use this signal in your implementation to inform ActionThreadBase manager the job is done.
0066      */
0067     void signalDone();
0068 
0069 public Q_SLOTS:
0070 
0071     /**
0072      * Call this method to cancel job.
0073      */
0074     void cancel();
0075 
0076 public:
0077 
0078     /**
0079      * Timer to determine the running time of the job.
0080      */
0081     QElapsedTimer m_timer;
0082 
0083 protected:
0084 
0085     /**
0086      * You can use this boolean in your implementation to know if job must be canceled.
0087      */
0088     bool m_cancel;
0089 };
0090 
0091 /**
0092  * Define a QHash of job/priority to process by ActionThreadBase manager.
0093  * Priority value can be used to control the run queue's order of execution.
0094  * Zero priority want mean to process job with higher priority.
0095  */
0096 typedef QHash<ActionJob*, int> ActionJobCollection;
0097 
0098 // -------------------------------------------------------------------------------------------------------
0099 
0100 class DIGIKAM_EXPORT ActionThreadBase : public QThread
0101 {
0102     Q_OBJECT
0103 
0104 public:
0105 
0106     explicit ActionThreadBase(QObject* const parent = nullptr);
0107     ~ActionThreadBase() override;
0108 
0109     /**
0110      * Adjust maximum number of threads used to parallelize collection of job processing.
0111      */
0112     void setMaximumNumberOfThreads(int n);
0113 
0114     /**
0115      * Return the maximum number of threads used to parallelize collection of job processing.
0116      */
0117     int  maximumNumberOfThreads()   const;
0118 
0119     /**
0120      * Reset maximum number of threads used to parallelize collection of job processing to max core detected on computer.
0121      * This method is called in constructor.
0122      */
0123     void setDefaultMaximumNumberOfThreads();
0124 
0125     /**
0126      * Cancel processing of current jobs under progress.
0127      */
0128     void cancel(bool isCancel = true);
0129 
0130 protected:
0131 
0132     /**
0133      * Main thread loop used to process jobs in todo list.
0134      */
0135     void run()                            override;
0136 
0137     /**
0138      * Append a collection of jobs to process into QThreadPool.
0139      *  Jobs are add to pending lists and will be deleted by ActionThreadBase, not QThreadPool.
0140      */
0141     void appendJobs(const ActionJobCollection& jobs);
0142 
0143     /**
0144      * Return true if list of pending jobs to process is empty.
0145      */
0146     bool isEmpty()                  const;
0147 
0148     /**
0149      * Return the number of pending jobs to process.
0150      */
0151     int pendingCount()              const;
0152 
0153 protected Q_SLOTS:
0154 
0155     void slotJobFinished();
0156 
0157 private:
0158 
0159     class Private;
0160     Private* const d;
0161 };
0162 
0163 } // namespace Digikam
0164 
0165 #endif // DIGIKAM_ACTION_THREAD_BASE_H