CPPMyth
Library to interoperate with MythTV server
Loading...
Searching...
No Matches
threadpool.h
1#pragma once
2/*
3 * Copyright (C) 2015-2026 Jean-Luc Barriere
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; see the file COPYING. If not, write to
17 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301 USA
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 */
22
23#include "thread.h"
24#include "event.h"
25
26#include <queue>
27#include <set>
28
29#ifdef NSROOT
30namespace NSROOT {
31#endif
32namespace OS
33{
34
35 class Worker;
36
37 class WorkerThread;
38
39 class ThreadPool
40 {
41 friend class WorkerThread;
42 public:
43 ThreadPool();
44 ThreadPool(unsigned size);
45 ~ThreadPool();
46
47 bool enqueue(Worker* worker);
48
49 unsigned max_size() const { return m_size; }
50
51 void set_max_size(unsigned size);
52
53 void set_keep_alive(unsigned millisec);
54
55 unsigned size() const;
56
57 unsigned queue_size() const;
58 bool is_queue_empty() const;
59 bool wait_empty();
60 bool wait_empty_for(unsigned millisec);
61
62 void suspend();
63 void resume();
64 bool is_suspended() const;
65
66 void reset();
67 void stop();
68 void start();
69 bool is_stopped() const;
70
71 private:
72 unsigned m_size;
73 unsigned m_keepAlive;
74 unsigned m_poolSize;
75 unsigned m_waitingCount;
76 volatile bool m_stopped;
77 volatile bool m_suspended;
78 volatile bool m_empty;
79
80 std::queue<Worker*> m_queue;
81 std::set<WorkerThread*> m_pool;
82 mutable Mutex m_mutex;
83 Condition<volatile bool> m_condition;
84 Event m_queueFill;
85 Event m_queueEmpty;
86
87 Worker* pop_queue(WorkerThread* _thread);
88 void wait_queue(WorkerThread* _thread);
89 void start_thread(WorkerThread* _thread);
90 void finalize_thread(WorkerThread* _thread);
91 void __resize();
92 };
93
94 class Worker
95 {
96 friend class ThreadPool;
97 public:
98 Worker() : m_queued(false) { }
99 virtual ~Worker() { }
100 virtual void process() = 0;
101
102 private:
103 bool m_queued;
104 };
105
106 class WorkerThread : public Thread
107 {
108 public:
109 WorkerThread(ThreadPool& pool)
110 : Thread()
111 , m_threadPool(pool) { m_finalizeOnStop = true; }
112
113 void* process(void)
114 {
115 bool waiting = false;
116
117 while (!is_stopped())
118 {
119 Worker* worker = m_threadPool.pop_queue(this);
120 if (worker != nullptr)
121 {
122 worker->process();
123 delete worker;
124 waiting = false;
125 }
126 else if (!waiting)
127 {
128 m_threadPool.wait_queue(this);
129 waiting = true;
130 }
131 else
132 break;
133 }
134
135 return nullptr;
136 }
137
138 void finalize(void)
139 {
140 m_threadPool.finalize_thread(this);
141 }
142
143 private:
144 ThreadPool& m_threadPool;
145 };
146
147}
148#ifdef NSROOT
149}
150#endif