File indexing completed on 2024-04-21 04:01:28

0001 /* -*- C++ -*-
0002     This file declares the QueueInterface class.
0003 
0004     SPDX-FileCopyrightText: 2005-2013 Mirko Boehm <mirko@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef QueueInterface_H
0010 #define QueueInterface_H
0011 
0012 #include <QList>
0013 #include <QObject>
0014 
0015 #include "jobinterface.h"
0016 #include "jobpointer.h"
0017 #include "threadweaver_export.h"
0018 
0019 namespace ThreadWeaver
0020 {
0021 class Job;
0022 class State;
0023 class WeaverObserver;
0024 
0025 /** WeaverInterface provides a common interface for weaver implementations.
0026 
0027 In most cases, it is sufficient for an application to hold exactly one
0028 ThreadWeaver job queue. To execute jobs in a specific order, use job
0029 dependencies. To limit the number of jobs of a certain type that can
0030 be executed at the same time, use resource restrictions. To handle
0031 special requirements of the application when it comes to the order of
0032 execution of jobs, implement a special queue policy and apply it to
0033 the jobs.
0034 
0035 Users of the ThreadWeaver API are encouraged to program to this
0036 interface, instead of the implementation. This way, implementation
0037 changes will not affect user programs.
0038 
0039 This interface can be used for example to implement adapters and
0040 decorators. The member documentation is provided in the Weaver and
0041 WeaverImpl classes.
0042 */
0043 
0044 class THREADWEAVER_EXPORT QueueInterface
0045 {
0046 public:
0047     virtual ~QueueInterface()
0048     {
0049     }
0050     /** Return the state of the weaver object. */
0051     virtual const State *state() const = 0;
0052 
0053     /** Shut down the queue.
0054      * Tells all threads to exit, and changes to Destructed state.
0055      * It is safe to destroy the queue once this method returns.
0056      */
0057     virtual void shutDown() = 0;
0058 
0059     /** Set the maximum number of threads this Weaver object may start. */
0060     virtual void setMaximumNumberOfThreads(int cap) = 0;
0061 
0062     /** Get the maximum number of threads this Weaver may start. */
0063     virtual int maximumNumberOfThreads() const = 0;
0064 
0065     /** Returns the current number of threads in the inventory. */
0066     virtual int currentNumberOfThreads() const = 0;
0067 
0068     /** Queue a vector of jobs.
0069 
0070     It depends on the state if execution of the job will be attempted
0071     immediately. In suspended state, jobs can be added to the queue,
0072     but the threads remain suspended. In WorkongHard state, an idle
0073     thread may immediately execute the job, or it might be queued if
0074     all threads are busy.
0075 
0076     JobPointer is a shared pointer. This means the object pointed to will be deleted if this object
0077     is the last remaining reference to it. Keep a JobPointer to the job to avoid automatic deletion.
0078     */
0079     virtual void enqueue(const QList<JobPointer> &jobs) = 0;
0080 
0081     /** Remove a job from the queue.
0082      *
0083      * If the job was queued but not started so far, it is removed from the queue.
0084      *
0085      * You can always call dequeue, it will return true if the job was dequeued. However if the job is not in the queue anymore,
0086      * it is already being executed, it is too late to dequeue, and dequeue will return false. The return value is thread-safe - if
0087      * true is returned, the job was still waiting, and has been dequeued. If not, the job was not waiting in the queue.
0088      *
0089      * Modifying queued jobs is best done on a suspended queue. Often, for example at the end of an application, it is sufficient
0090      * to dequeue all jobs (which leaves only the ones mid-air in threads), call finish (that will wait for all the mid air jobs to
0091      * complete), and then exit. Without dequeue(), all jobs in the queue would be executed during finish().
0092      * @see requestAbort for aborting jobs during execution
0093      * @return true if the job was waiting and has been dequeued
0094      * @return false if the job was not found waiting in the queue
0095      */
0096     virtual bool dequeue(const JobPointer &job) = 0;
0097 
0098     /** Remove all queued jobs.
0099      *
0100      * All waiting jobs will be dequeued. The semantics are the same as for dequeue(JobInterface).
0101      *
0102      * @see dequeue(JobInterface)
0103      */
0104     virtual void dequeue() = 0;
0105     /** Finish all queued operations, then return.
0106 
0107     This method is used in imperative (not event driven) programs that
0108     cannot react on events to have the controlling (main) thread wait
0109     wait for the jobs to finish. The call will block the calling
0110     thread and return when all queued jobs have been processed.
0111 
0112     Warning: This will suspend your thread!
0113     Warning: If one of your jobs enters an infinite loop, this
0114     will never return! */
0115     virtual void finish() = 0;
0116     /** Suspend job execution.
0117     When suspending, all threads are allowed to finish the
0118     currently assigned job but will not receive a new
0119     assignment.
0120     When all threads are done processing the assigned job, the
0121     signal suspended will() be emitted.
0122     If you call suspend() and there are no jobs left to
0123     be done, you will immediately receive the suspended()
0124     signal. */
0125     virtual void suspend() = 0;
0126     /** Resume job queueing.
0127     @see suspend
0128     */
0129     virtual void resume() = 0;
0130     /** Is the queue empty?
0131     The queue is empty if no more jobs are queued. */
0132     virtual bool isEmpty() const = 0;
0133     /** Is the weaver idle?
0134     The weaver is idle if no jobs are queued and no jobs are processed
0135     by the threads. */
0136     virtual bool isIdle() const = 0;
0137     /** Returns the number of pending jobs.
0138     This will return the number of queued jobs. Jobs that are
0139     currently being executed are not part of the queue. All jobs in
0140     the queue are waiting to be executed.
0141     */
0142     virtual int queueLength() const = 0;
0143 
0144     /** Request aborts of the currently executed jobs.
0145     It is important to understand that aborts are requested, but
0146     cannot be guaranteed, as not all Job classes support it. It is up
0147     to the application to decide if and how job aborts are
0148     necessary. */
0149     virtual void requestAbort() = 0;
0150 
0151     /** @brief Reschedule the jobs in the queue.
0152      * This method triggers a scheduling attempt to perform jobs. It will schedule enqueued jobs to be executed by idle threads.
0153      * It should only be necessary to call it if the canRun() status of a job changed spontaneously due to external reasons. */
0154     virtual void reschedule() = 0;
0155 };
0156 
0157 }
0158 
0159 #endif