]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_async.h
c5c0e091daaf99fd334e10159d20dc47e4fb22ae
[dragonfireclient.git] / src / script / cpp_api / s_async.h
1 /*
2 Minetest
3 Copyright (C) 2013 sapier, <sapier AT gmx DOT net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program 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 along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef L_ASYNC_EVENTS_H_
21 #define L_ASYNC_EVENTS_H_
22
23 #include <vector>
24 #include <map>
25
26 #include "jthread/jthread.h"
27 #include "jthread/jmutex.h"
28 #include "jthread/jsemaphore.h"
29 #include "debug.h"
30 #include "lua.h"
31 #include "cpp_api/s_base.h"
32
33 // Forward declarations
34 class AsyncEngine;
35
36
37 // Declarations
38
39 // Data required to queue a job
40 struct LuaJobInfo {
41         // Function to be called in async environment
42         std::string serializedFunction;
43         // Parameter to be passed to function
44         std::string serializedParams;
45         // Result of function call
46         std::string serializedResult;
47         // JobID used to identify a job and match it to callback
48         unsigned int JobId;
49
50         bool valid;
51 };
52
53 // Asynchronous working environment
54 class AsyncWorkerThread : public JThread, public ScriptApiBase {
55 public:
56         /**
57          * default constructor
58          * @param pointer to job dispatcher
59          */
60         AsyncWorkerThread(AsyncEngine* jobDispatcher, unsigned int threadNum);
61
62         virtual ~AsyncWorkerThread();
63
64         void* Thread();
65
66 private:
67         AsyncEngine* m_JobDispatcher;
68
69         // Thread number. Used for debug output
70         unsigned int m_threadnum;
71
72 };
73
74 // Asynchornous thread and job management
75 class AsyncEngine {
76         friend class AsyncWorkerThread;
77 public:
78         AsyncEngine();
79         ~AsyncEngine();
80
81         /**
82          * Register function to be used within engine
83          * @param name Function name to be used within Lua environment
84          * @param func C function to be called
85          */
86         bool registerFunction(const char* name, lua_CFunction func);
87
88         /**
89          * Create async engine tasks and lock function registration
90          * @param numEngines Number of async threads to be started
91          */
92         void Initialize(unsigned int numEngines);
93
94         /**
95          * queue/run a async job
96          * @param func Serialized lua function
97          * @param params Serialized parameters
98          * @return jobid The job is queued
99          */
100         unsigned int doAsyncJob(std::string func, std::string params);
101
102         /**
103          * Engine step to process finished jobs
104          *   the engine step is one way to pass events back, PushFinishedJobs another
105          * @param L The Lua stack
106          * @param errorhandler Stack index of the Lua error handler
107          */
108         void Step(lua_State *L, int errorhandler);
109
110         /**
111          * Push a list of finished jobs onto the stack
112          * @param L The Lua stack
113          */
114         void PushFinishedJobs(lua_State *L);
115
116 protected:
117         /**
118          * Get a Job from queue to be processed
119          *  this function blocks until a job is ready
120          * @return a job to be processed
121          */
122         LuaJobInfo getJob();
123
124         /**
125          * Put a Job result back to result queue
126          * @param result result of completed job
127          */
128         void putJobResult(LuaJobInfo result);
129
130         /**
131          * Initialize environment with current registred functions
132          *  this function adds all functions registred by registerFunction to the
133          *  passed lua stack
134          * @param L Lua stack to initialize
135          * @param top Stack position
136          */
137         void PrepareEnvironment(lua_State* L, int top);
138
139 private:
140
141         // Stack index of error handler
142         int m_errorhandler;
143
144         // variable locking the engine against further modification
145         bool m_initDone;
146
147         // Internal store for registred functions
148         std::map<std::string, lua_CFunction> m_FunctionList;
149
150         // Internal counter to create job IDs
151         unsigned int m_JobIdCounter;
152
153         // Mutex to protect job queue
154         JMutex m_JobQueueMutex;
155
156         // Job queue
157         std::vector<LuaJobInfo> m_JobQueue;
158
159         // Mutex to protect result queue
160         JMutex m_ResultQueueMutex;
161         // Result queue
162         std::vector<LuaJobInfo> m_ResultQueue;
163
164         // List of current worker threads
165         std::vector<AsyncWorkerThread*> m_WorkerThreads;
166
167         // Counter semaphore for job dispatching
168         JSemaphore m_JobQueueCounter;
169 };
170
171 #endif // L_ASYNC_EVENTS_H_