@@ -21,18 +21,21 @@ namespace dispatch
2121{
2222#pragma mark - TaskPriority
2323
24- struct TaskPriority {
24+ struct TaskPriority
25+ {
2526 TaskPriority (QUEUE_PRIORITY priority, Functor task) : priority(priority), task(task), timestamp(std::clock()){}
2627
2728 QUEUE_PRIORITY priority;
2829 Functor task;
2930 std::clock_t timestamp;
3031 };
32+
3133#pragma mark - Queue
3234
3335 typedef std::function<void (Functor)> AppendTask;
3436
35- struct QueueImpl {
37+ struct QueueImpl
38+ {
3639 QUEUE_PRIORITY priority;
3740 AppendTask append_task;
3841
@@ -47,7 +50,8 @@ namespace dispatch
4750
4851#pragma mark - ThreadPool
4952
50- class ThreadPool {
53+ class ThreadPool
54+ {
5155 public:
5256 ThreadPool (size_t );
5357 static ThreadPool* instance ();
@@ -64,6 +68,7 @@ namespace dispatch
6468 std::mutex main_mutex;
6569 std::condition_variable main_condition;
6670
71+ Functor main_loop_need_update;
6772 private:
6873 friend class QueueImpl ;
6974
@@ -73,7 +78,8 @@ namespace dispatch
7378
7479#pragma mark - Task comparator
7580
76- bool operator <(const QueueImpl::Task& firsTask, const QueueImpl::Task& secondTask) {
81+ bool operator <(const QueueImpl::Task& firsTask, const QueueImpl::Task& secondTask)
82+ {
7783 if ( firsTask->priority == secondTask->priority )
7884 return firsTask->timestamp > secondTask->timestamp ;
7985 else
@@ -82,10 +88,13 @@ namespace dispatch
8288
8389#pragma mark - ThreadPool
8490
85- void ThreadPool::add_worker (){
86- workers.push_back (std::thread ([&]{
91+ void ThreadPool::add_worker ()
92+ {
93+ workers.push_back (std::thread ([&]
94+ {
8795 QueueImpl::Task task;
88- while (true ){
96+ while (true )
97+ {
8998 {
9099 std::unique_lock<std::mutex> lock (this ->queue_mutex );
91100
@@ -103,24 +112,27 @@ namespace dispatch
103112 }));
104113 }
105114
106- ThreadPool::ThreadPool (size_t threads) : stop(false ){
115+ ThreadPool::ThreadPool (size_t threads) : stop(false )
116+ {
107117 for (int i = 0 ; i < threads; ++i)
108118 add_worker ();
109119 }
110120
111- ThreadPool::~ThreadPool (){
121+ ThreadPool::~ThreadPool ()
122+ {
112123 stop = true ;
113124 condition.notify_all ();
114-
115- // the destructor joins all threads
125+
116126 for (size_t i = 0 ;i<workers.size ();++i)
117127 workers[i].join ();
118128 }
119129
120- ThreadPool* ThreadPool::instance (){
130+ ThreadPool* ThreadPool::instance ()
131+ {
121132 static std::once_flag flag;
122133 static ThreadPool* instance = nullptr ;
123- std::call_once (flag, [](){
134+ std::call_once (flag, []()
135+ {
124136 int default_not_computable_value = 5 ;
125137 int number_of_threads = std::thread::hardware_concurrency ();
126138 instance = new ThreadPool (number_of_threads?: default_not_computable_value);
@@ -130,47 +142,63 @@ namespace dispatch
130142
131143#pragma mark -
132144
133- Queue get_main_queue (){
134- return std::make_shared<QueueImpl>([](Functor task) {
145+ Queue get_main_queue ()
146+ {
147+ return std::make_shared<QueueImpl>([](Functor task)
148+ {
135149 std::unique_lock<std::mutex> lock (ThreadPool::instance ()->main_mutex );
136150 ThreadPool::instance ()->main_queue .push (std::make_shared<TaskPriority>(QUEUE_PRIORITY ::HIGH , task));
151+ if (ThreadPool::instance ()->main_loop_need_update != nullptr )
152+ ThreadPool::instance ()->main_loop_need_update ();
137153 });
138154 }
139155
140- void process_main_loop (){
156+ Queue get_queue_with_priority (QUEUE_PRIORITY priority)
157+ {
158+ return std::make_shared<QueueImpl>(priority, [=](Functor task)
159+ {
160+ {
161+ std::unique_lock<std::mutex> lock (ThreadPool::instance ()->queue_mutex );
162+ ThreadPool::instance ()->tasks .push (std::make_shared<TaskPriority>(priority, task));
163+ }
164+ ThreadPool::instance ()->condition .notify_one ();
165+ });
166+ }
167+
168+ void process_main_loop ()
169+ {
141170 ThreadPool* pool = ThreadPool::instance ();
142171 std::unique_lock<std::mutex> lock (pool->main_mutex );
143- while (!pool->main_queue .empty ()){
172+ while (!pool->main_queue .empty ())
173+ {
144174 QueueImpl::Task task = pool->main_queue .front ();
145175 pool->main_queue .pop ();
146176 task->task ();
147177 }
148178 }
149179
150- void main_loop (Functor function){
180+ void main_loop (Functor function)
181+ {
151182 Queue main_queue = get_main_queue ();
152- while (!ThreadPool::instance ()->stop ){
183+ while (!ThreadPool::instance ()->stop )
184+ {
153185 async (main_queue, function);
154186 process_main_loop ();
155187 }
156188 }
157189
158- void async (Queue queue, Functor function){
190+ void async (Queue queue, Functor function)
191+ {
159192 queue->append_task (function);
160193 }
161194
162- void exit (){
195+ void exit ()
196+ {
163197 ThreadPool::instance ()->stop = true ;
164198 }
165199
166- Queue get_queue_with_priority (QUEUE_PRIORITY priority){
167- return std::make_shared<QueueImpl>(priority, [=](Functor task) {
168- {
169- std::unique_lock<std::mutex> lock (ThreadPool::instance ()->queue_mutex );
170- ThreadPool::instance ()->tasks .push (std::make_shared<TaskPriority>(priority, task));
171- }
172-
173- ThreadPool::instance ()->condition .notify_one ();
174- });
200+ void set_main_loop_process_callback (Functor update_callback)
201+ {
202+ ThreadPool::instance ()->main_loop_need_update = update_callback;
175203 }
176204}
0 commit comments