1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
15 class cmWorkerPoolInternal
;
17 /** @class cmWorkerPool
18 * @brief Thread pool with job queue
24 * Return value and output of an external process.
31 return (this->ExitStatus
!= 0) || (this->TermSignal
!= 0) ||
32 !this->ErrorMessage
.empty();
35 std::int64_t ExitStatus
= 0;
39 std::string ErrorMessage
;
43 * Abstract job class for concurrent job processing.
48 JobT(JobT
const&) = delete;
49 JobT
& operator=(JobT
const&) = delete;
59 * Fence jobs require that:
60 * - all jobs before in the queue have been processed
61 * - no jobs later in the queue will be processed before this job was
64 bool IsFence() const { return this->Fence_
; }
68 * Protected default constructor
70 JobT(bool fence
= false)
76 * Abstract processing interface that must be implement in derived classes.
78 virtual void Process() = 0;
81 * Get the worker pool.
82 * Only valid during the JobT::Process() call!
84 cmWorkerPool
* Pool() const { return this->Pool_
; }
88 * Only valid during the JobT::Process() call!
90 void* UserData() const { return this->Pool_
->UserData(); }
93 * Get the worker index.
94 * This is the index of the thread processing this job and is in the range
96 * Concurrently processing jobs will never have the same WorkerIndex().
97 * Only valid during the JobT::Process() call!
99 unsigned int WorkerIndex() const { return this->WorkerIndex_
; }
102 * Run an external read only process.
103 * Use only during JobT::Process() call!
105 bool RunProcess(ProcessResultT
& result
,
106 std::vector
<std::string
> const& command
,
107 std::string
const& workingDirectory
);
110 //! Needs access to Work()
111 friend class cmWorkerPoolInternal
;
112 //! Worker thread entry method.
113 void Work(cmWorkerPool
* pool
, unsigned int workerIndex
)
116 this->WorkerIndex_
= workerIndex
;
120 cmWorkerPool
* Pool_
= nullptr;
121 unsigned int WorkerIndex_
= 0;
128 using JobHandleT
= std::unique_ptr
<JobT
>;
131 * Fence job base class
133 class JobFenceT
: public JobT
141 void Process() override
{}
145 * Fence job that aborts the worker pool.
147 * Useful as the last job in the job queue.
149 class JobEndT
: JobFenceT
153 void Process() override
{ this->Pool()->Abort(); }
161 * Number of worker threads.
163 unsigned int ThreadCount() const { return this->ThreadCount_
; }
166 * Set the number of worker threads.
168 * Calling this method during Process() has no effect.
170 void SetThreadCount(unsigned int threadCount
);
173 * Blocking function that starts threads to process all Jobs in the queue.
175 * This method blocks until a job calls the Abort() method.
176 * @arg threadCount Number of threads to process jobs.
177 * @arg userData Common user data pointer available in all Jobs.
179 bool Process(void* userData
= nullptr);
182 * User data reference passed to Process().
184 * Only valid during Process().
186 void* UserData() const { return this->UserData_
; }
188 // -- Job processing interface
191 * Clears the job queue and aborts all worker threads.
193 * This method is thread safe and can be called from inside a job.
198 * Push job to the queue.
200 * This method is thread safe and can be called from inside a job or before
203 bool PushJob(JobHandleT
&& jobHandle
);
206 * Push job to the queue
208 * This method is thread safe and can be called from inside a job or before
211 template <class T
, typename
... Args
>
212 bool EmplaceJob(Args
&&... args
)
214 return this->PushJob(cm::make_unique
<T
>(std::forward
<Args
>(args
)...));
218 void* UserData_
= nullptr;
219 unsigned int ThreadCount_
= 1;
220 std::unique_ptr
<cmWorkerPoolInternal
> Int_
;