X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fthread.h;h=73e9beb806f44d8effc6dd8e3a3bec3f82adf23f;hb=e8fd1ce62331146fae0e98ce4a94d3720f308abf;hp=bb8e03317b8a685a2c3834b72903d85ee1fee175;hpb=e9e9fd7c3f12bc5119b567ad37527d777859dbc0;p=oweals%2Fminetest.git diff --git a/src/util/thread.h b/src/util/thread.h index bb8e03317..73e9beb80 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -17,54 +17,46 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef UTIL_THREAD_HEADER -#define UTIL_THREAD_HEADER +#pragma once -#include "../irrlichttypes.h" -#include "../jthread/jthread.h" -#include "../jthread/jmutex.h" -#include "../jthread/jmutexautolock.h" +#include "irrlichttypes.h" +#include "threading/thread.h" +#include "threading/mutex_auto_lock.h" +#include "porting.h" +#include "log.h" +#include "container.h" template class MutexedVariable { public: - MutexedVariable(T value): + MutexedVariable(const T &value): m_value(value) - { - } + {} T get() { - JMutexAutoLock lock(m_mutex); + MutexAutoLock lock(m_mutex); return m_value; } - void set(T value) + void set(const T &value) { - JMutexAutoLock lock(m_mutex); + MutexAutoLock lock(m_mutex); m_value = value; } - - // You'll want to grab this in a SharedPtr - JMutexAutoLock * getLock() - { - return new JMutexAutoLock(m_mutex); - } - + // You pretty surely want to grab the lock when accessing this T m_value; - private: - JMutex m_mutex; + std::mutex m_mutex; }; /* A single worker thread - multiple client threads queue framework. */ template -class GetResult -{ +class GetResult { public: Key key; T item; @@ -72,34 +64,27 @@ public: }; template -class ResultQueue: public MutexedQueue< GetResult > -{ +class ResultQueue : public MutexedQueue > { }; template -class CallerInfo -{ +class CallerInfo { public: Caller caller; Data data; - ResultQueue< Key, T, Caller, Data>* dest; + ResultQueue *dest; }; template -class GetRequest -{ +class GetRequest { public: - GetRequest() - { - } - GetRequest(Key a_key) - { - key = a_key; - } - ~GetRequest() + GetRequest() = default; + ~GetRequest() = default; + + GetRequest(const Key &a_key): key(a_key) { } - + Key key; std::list > callers; }; @@ -112,41 +97,38 @@ public: * @param CallerData data passed back to caller */ template -class RequestQueue -{ +class RequestQueue { public: bool empty() { return m_queue.empty(); } - void add(Key key, Caller caller, CallerData callerdata, - ResultQueue *dest) + void add(const Key &key, Caller caller, CallerData callerdata, + ResultQueue *dest) { - JMutexAutoLock lock(m_queue.getMutex()); - - /* - If the caller is already on the list, only update CallerData - */ - for(typename std::list< GetRequest >::iterator - i = m_queue.getList().begin(); - i != m_queue.getList().end(); ++i) + typename std::deque >::iterator i; + typename std::list >::iterator j; + { - GetRequest &request = *i; - - if(request.key == key) - { - for(typename std::list< CallerInfo >::iterator - i = request.callers.begin(); - i != request.callers.end(); ++i) - { - CallerInfo &ca = *i; - if(ca.caller == caller) - { + MutexAutoLock lock(m_queue.getMutex()); + + /* + If the caller is already on the list, only update CallerData + */ + for (i = m_queue.getQueue().begin(); i != m_queue.getQueue().end(); ++i) { + GetRequest &request = *i; + if (request.key != key) + continue; + + for (j = request.callers.begin(); j != request.callers.end(); ++j) { + CallerInfo &ca = *j; + if (ca.caller == caller) { ca.data = callerdata; return; } } + CallerInfo ca; ca.caller = caller; ca.data = callerdata; @@ -167,22 +149,25 @@ public: ca.data = callerdata; ca.dest = dest; request.callers.push_back(ca); - - m_queue.getList().push_back(request); + + m_queue.push_back(request); } - GetRequest pop(bool wait_if_empty=false) + GetRequest pop(unsigned int timeout_ms) { - return m_queue.pop_front(wait_if_empty); + return m_queue.pop_front(timeout_ms); } - void pushResult(GetRequest req, - T res) { + GetRequest pop() + { + return m_queue.pop_frontNoEx(); + } - for(typename std::list< CallerInfo >::iterator + void pushResult(GetRequest req, T res) + { + for (typename std::list >::iterator i = req.callers.begin(); - i != req.callers.end(); ++i) - { + i != req.callers.end(); ++i) { CallerInfo &ca = *i; GetResult result; @@ -197,8 +182,47 @@ public: } private: - MutexedQueue< GetRequest > m_queue; + MutexedQueue > m_queue; }; -#endif +class UpdateThread : public Thread +{ +public: + UpdateThread(const std::string &name) : Thread(name + "Update") {} + ~UpdateThread() = default; + + void deferUpdate() { m_update_sem.post(); } + + void stop() + { + Thread::stop(); + + // give us a nudge + m_update_sem.post(); + } + + void *run() + { + BEGIN_DEBUG_EXCEPTION_HANDLER + + while (!stopRequested()) { + m_update_sem.wait(); + // Set semaphore to 0 + while (m_update_sem.wait(0)); + + if (stopRequested()) break; + + doUpdate(); + } + + END_DEBUG_EXCEPTION_HANDLER + return NULL; + } + +protected: + virtual void doUpdate() = 0; + +private: + Semaphore m_update_sem; +};