Luanti 5.15.0-dev
 
Loading...
Searching...
No Matches
thread.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5#pragma once
6
7#include <utility> // std::move
8#include "irrlichttypes.h"
9#include "threading/thread.h"
11#include "container.h"
12
13template<typename T>
15{
16public:
17 // default initialization
19
20 MutexedVariable(const T &value):
21 m_value(value) {}
22 MutexedVariable(T &&value):
23 m_value(std::move(value)) {}
24
25 T get()
26 {
28 return m_value;
29 }
30
31 void set(const T &value)
32 {
34 m_value = value;
35 }
36
37 void set(T &&value)
38 {
40 m_value = std::move(value);
41 }
42
43private:
45 std::mutex m_mutex;
46};
47
48/*
49 A single worker thread - multiple client threads queue framework.
50*/
51template<typename Key, typename T, typename Caller, typename CallerData>
52class GetResult {
53public:
54 Key key;
56 std::pair<Caller, CallerData> caller;
57};
58
59template<typename Key, typename T, typename Caller, typename CallerData>
60class ResultQueue : public MutexedQueue<GetResult<Key, T, Caller, CallerData> > {
61};
62
63template<typename Caller, typename Data, typename Key, typename T>
70
71template<typename Key, typename T, typename Caller, typename CallerData>
73public:
75
76 GetRequest() = default;
77 ~GetRequest() = default;
78
79 GetRequest(const Key &a_key): key(a_key)
80 {
81 }
82
83 Key key;
84 std::vector<caller_info_type> callers;
85};
86
94template<typename Key, typename T, typename Caller, typename CallerData>
96public:
100
101 bool empty() const
102 {
103 return m_queue.empty();
104 }
105
106 void add(const Key &key, Caller caller, CallerData callerdata,
107 result_queue_type *dest)
108 {
109 {
110 MutexAutoLock lock(m_queue.getMutex());
111
112 for (auto &request : m_queue.getQueue()) {
113 if (request.key != key)
114 continue;
115
116 // If the caller is already on the list, only update CallerData
117 for (auto &ca : request.callers) {
118 if (ca.caller == caller) {
119 ca.data = callerdata;
120 return;
121 }
122 }
123
124 // Or add this caller
126 ca.caller = caller;
127 ca.data = callerdata;
128 ca.dest = dest;
129 request.callers.push_back(std::move(ca));
130 return;
131 }
132 }
133
134 // Else add a new request to the queue
135 request_type request;
136 request.key = key;
138 ca.caller = caller;
139 ca.data = callerdata;
140 ca.dest = dest;
141 request.callers.push_back(std::move(ca));
142
143 m_queue.push_back(std::move(request));
144 }
145
146 request_type pop(unsigned int timeout_ms)
147 {
148 return m_queue.pop_front(timeout_ms);
149 }
150
152 {
153 return m_queue.pop_frontNoEx();
154 }
155
156 void pushResult(const request_type &req, const T &res)
157 {
158 for (auto &ca : req.callers) {
159 result_type result;
160
161 result.key = req.key;
162 result.item = res;
163 result.caller.first = ca.caller;
164 result.caller.second = ca.data;
165
166 ca.dest->push_back(std::move(result));
167 }
168 }
169
170private:
172};
173
174class UpdateThread : public Thread
175{
176public:
177 UpdateThread(const std::string &name) : Thread(name + "Update") {}
178 ~UpdateThread() = default;
179
181
182 void stop()
183 {
184 Thread::stop();
185
186 // give us a nudge
188 }
189
190 void *run()
191 {
193
194 while (!stopRequested()) {
196 // Set semaphore to 0
197 while (m_update_sem.wait(0));
198
199 if (stopRequested()) break;
200
201 doUpdate();
202 }
203
205
206 return NULL;
207 }
208
209protected:
210 virtual void doUpdate() = 0;
211
212private:
214};
Definition thread.h:64
ResultQueue< Key, T, Caller, Data > * dest
Definition thread.h:68
Data data
Definition thread.h:67
Caller caller
Definition thread.h:66
Definition thread.h:72
std::vector< caller_info_type > callers
Definition thread.h:84
GetRequest()=default
~GetRequest()=default
Key key
Definition thread.h:83
GetRequest(const Key &a_key)
Definition thread.h:79
CallerInfo< Caller, CallerData, Key, T > caller_info_type
Definition thread.h:74
Definition thread.h:52
T item
Definition thread.h:55
std::pair< Caller, CallerData > caller
Definition thread.h:56
Key key
Definition thread.h:54
Definition container.h:126
void push_back(const T &t)
Definition container.h:139
Definition thread.h:15
MutexedVariable(const T &value)
Definition thread.h:20
MutexedVariable()
Definition thread.h:18
T m_value
Definition thread.h:44
std::mutex m_mutex
Definition thread.h:45
void set(T &&value)
Definition thread.h:37
void set(const T &value)
Definition thread.h:31
T get()
Definition thread.h:25
MutexedVariable(T &&value)
Definition thread.h:22
Notes for RequestQueue usage.
Definition thread.h:95
GetResult< Key, T, Caller, CallerData > result_type
Definition thread.h:98
bool empty() const
Definition thread.h:101
void add(const Key &key, Caller caller, CallerData callerdata, result_queue_type *dest)
Definition thread.h:106
MutexedQueue< request_type > m_queue
Definition thread.h:171
void pushResult(const request_type &req, const T &res)
Definition thread.h:156
GetRequest< Key, T, Caller, CallerData > request_type
Definition thread.h:97
request_type pop()
Definition thread.h:151
ResultQueue< Key, T, Caller, CallerData > result_queue_type
Definition thread.h:99
request_type pop(unsigned int timeout_ms)
Definition thread.h:146
Definition thread.h:60
Definition semaphore.h:18
void post(unsigned int num=1)
Definition semaphore.cpp:70
void wait()
Definition semaphore.cpp:85
Definition thread.h:57
bool stop()
Definition thread.cpp:140
bool stopRequested() const
Definition thread.h:92
Definition thread.h:175
virtual void doUpdate()=0
UpdateThread(const std::string &name)
Definition thread.h:177
~UpdateThread()=default
void deferUpdate()
Definition thread.h:180
Semaphore m_update_sem
Definition thread.h:213
void * run()
Definition thread.h:190
void stop()
Definition thread.h:182
#define END_DEBUG_EXCEPTION_HANDLER
Definition debug.h:77
#define BEGIN_DEBUG_EXCEPTION_HANDLER
Definition debug.h:76
std::lock_guard< std::mutex > MutexAutoLock
Definition mutex_auto_lock.h:31