Luanti 5.11.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 "irrlichttypes.h"
8#include "threading/thread.h"
10#include "porting.h"
11#include "log.h"
12#include "container.h"
13
14template<typename T>
16{
17public:
18 MutexedVariable(const T &value):
19 m_value(value)
20 {}
21
22 T get()
23 {
25 return m_value;
26 }
27
28 void set(const T &value)
29 {
31 m_value = value;
32 }
33
34 // You pretty surely want to grab the lock when accessing this
36private:
37 std::mutex m_mutex;
38};
39
40/*
41 A single worker thread - multiple client threads queue framework.
42*/
43template<typename Key, typename T, typename Caller, typename CallerData>
44class GetResult {
45public:
46 Key key;
48 std::pair<Caller, CallerData> caller;
49};
50
51template<typename Key, typename T, typename Caller, typename CallerData>
52class ResultQueue : public MutexedQueue<GetResult<Key, T, Caller, CallerData> > {
53};
54
55template<typename Caller, typename Data, typename Key, typename T>
62
63template<typename Key, typename T, typename Caller, typename CallerData>
65public:
66 GetRequest() = default;
67 ~GetRequest() = default;
68
69 GetRequest(const Key &a_key): key(a_key)
70 {
71 }
72
73 Key key;
74 std::list<CallerInfo<Caller, CallerData, Key, T> > callers;
75};
76
84template<typename Key, typename T, typename Caller, typename CallerData>
86public:
87 bool empty()
88 {
89 return m_queue.empty();
90 }
91
92 void add(const Key &key, Caller caller, CallerData callerdata,
94 {
95 typename std::deque<GetRequest<Key, T, Caller, CallerData> >::iterator i;
96 typename std::list<CallerInfo<Caller, CallerData, Key, T> >::iterator j;
97
98 {
100
101 /*
102 If the caller is already on the list, only update CallerData
103 */
104 for (i = m_queue.getQueue().begin(); i != m_queue.getQueue().end(); ++i) {
106 if (request.key != key)
107 continue;
108
109 for (j = request.callers.begin(); j != request.callers.end(); ++j) {
111 if (ca.caller == caller) {
112 ca.data = callerdata;
113 return;
114 }
115 }
116
118 ca.caller = caller;
119 ca.data = callerdata;
120 ca.dest = dest;
121 request.callers.push_back(ca);
122 return;
123 }
124 }
125
126 /*
127 Else add a new request to the queue
128 */
129
131 request.key = key;
133 ca.caller = caller;
134 ca.data = callerdata;
135 ca.dest = dest;
136 request.callers.push_back(ca);
137
138 m_queue.push_back(request);
139 }
140
142 {
143 return m_queue.pop_front(timeout_ms);
144 }
145
150
152 {
153 for (typename std::list<CallerInfo<Caller, CallerData, Key, T> >::iterator
154 i = req.callers.begin();
155 i != req.callers.end(); ++i) {
157
159
160 result.key = req.key;
161 result.item = res;
162 result.caller.first = ca.caller;
163 result.caller.second = ca.data;
164
165 ca.dest->push_back(result);
166 }
167 }
168
169private:
171};
172
173class UpdateThread : public Thread
174{
175public:
176 UpdateThread(const std::string &name) : Thread(name + "Update") {}
177 ~UpdateThread() = default;
178
180
181 void stop()
182 {
183 Thread::stop();
184
185 // give us a nudge
187 }
188
189 void *run()
190 {
192
193 while (!stopRequested()) {
195 // Set semaphore to 0
196 while (m_update_sem.wait(0));
197
198 if (stopRequested()) break;
199
200 doUpdate();
201 }
202
204
205 return NULL;
206 }
207
208protected:
209 virtual void doUpdate() = 0;
210
211private:
213};
Definition thread.h:56
ResultQueue< Key, T, Caller, Data > * dest
Definition thread.h:60
Data data
Definition thread.h:59
Caller caller
Definition thread.h:58
Definition thread.h:64
std::list< CallerInfo< Caller, CallerData, Key, T > > callers
Definition thread.h:74
GetRequest()=default
~GetRequest()=default
Key key
Definition thread.h:73
GetRequest(const Key &a_key)
Definition thread.h:69
Definition thread.h:44
T item
Definition thread.h:47
std::pair< Caller, CallerData > caller
Definition thread.h:48
Key key
Definition thread.h:46
Definition container.h:117
bool empty() const
Definition container.h:124
T pop_front(u32 wait_time_max_ms)
Definition container.h:160
std::deque< T > & getQueue()
Definition container.h:227
T pop_frontNoEx(u32 wait_time_max_ms)
Definition container.h:147
void push_back(const T &t)
Definition container.h:130
std::mutex & getMutex()
Definition container.h:225
Definition thread.h:16
MutexedVariable(const T &value)
Definition thread.h:18
T m_value
Definition thread.h:35
std::mutex m_mutex
Definition thread.h:37
void set(const T &value)
Definition thread.h:28
T get()
Definition thread.h:22
Notes for RequestQueue usage.
Definition thread.h:85
MutexedQueue< GetRequest< Key, T, Caller, CallerData > > m_queue
Definition thread.h:170
bool empty()
Definition thread.h:87
GetRequest< Key, T, Caller, CallerData > pop()
Definition thread.h:146
GetRequest< Key, T, Caller, CallerData > pop(unsigned int timeout_ms)
Definition thread.h:141
void add(const Key &key, Caller caller, CallerData callerdata, ResultQueue< Key, T, Caller, CallerData > *dest)
Definition thread.h:92
void pushResult(GetRequest< Key, T, Caller, CallerData > req, T res)
Definition thread.h:151
Definition thread.h:52
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()
Definition thread.h:92
Definition thread.h:174
virtual void doUpdate()=0
UpdateThread(const std::string &name)
Definition thread.h:176
~UpdateThread()=default
void deferUpdate()
Definition thread.h:179
Semaphore m_update_sem
Definition thread.h:212
void * run()
Definition thread.h:189
void stop()
Definition thread.h:181
#define END_DEBUG_EXCEPTION_HANDLER
Definition debug.h:78
#define BEGIN_DEBUG_EXCEPTION_HANDLER
Definition debug.h:77
std::lock_guard< std::mutex > MutexAutoLock
Definition mutex_auto_lock.h:31