Line data Source code
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 CPP_API_ASYNC_EVENTS_HEADER
21 : #define CPP_API_ASYNC_EVENTS_HEADER
22 :
23 : #include <vector>
24 : #include <deque>
25 : #include <map>
26 :
27 : #include "jthread/jthread.h"
28 : #include "jthread/jmutex.h"
29 : #include "jthread/jsemaphore.h"
30 : #include "debug.h"
31 : #include "lua.h"
32 : #include "cpp_api/s_base.h"
33 :
34 : // Forward declarations
35 : class AsyncEngine;
36 :
37 :
38 : // Declarations
39 :
40 : // Data required to queue a job
41 8 : struct LuaJobInfo {
42 : // Function to be called in async environment
43 : std::string serializedFunction;
44 : // Parameter to be passed to function
45 : std::string serializedParams;
46 : // Result of function call
47 : std::string serializedResult;
48 : // JobID used to identify a job and match it to callback
49 : unsigned int id;
50 :
51 : bool valid;
52 : };
53 :
54 : // Asynchronous working environment
55 : class AsyncWorkerThread : public JThread, public ScriptApiBase {
56 : public:
57 : /**
58 : * default constructor
59 : * @param pointer to job dispatcher
60 : */
61 : AsyncWorkerThread(AsyncEngine* jobDispatcher, unsigned int threadNum);
62 :
63 : virtual ~AsyncWorkerThread();
64 :
65 : void *Thread();
66 :
67 : private:
68 : AsyncEngine *jobDispatcher;
69 :
70 : // Thread number. Used for debug output
71 : unsigned int threadnum;
72 :
73 : };
74 :
75 : // Asynchornous thread and job management
76 : class AsyncEngine {
77 : friend class AsyncWorkerThread;
78 : public:
79 : AsyncEngine();
80 : ~AsyncEngine();
81 :
82 : /**
83 : * Register function to be used within engine
84 : * @param name Function name to be used within Lua environment
85 : * @param func C function to be called
86 : */
87 : bool registerFunction(const char* name, lua_CFunction func);
88 :
89 : /**
90 : * Create async engine tasks and lock function registration
91 : * @param numEngines Number of async threads to be started
92 : */
93 : void initialize(unsigned int numEngines);
94 :
95 : /**
96 : * Queue an async job
97 : * @param func Serialized lua function
98 : * @param params Serialized parameters
99 : * @return jobid The job is queued
100 : */
101 : unsigned int queueAsyncJob(std::string func, std::string params);
102 :
103 : /**
104 : * Engine step to process finished jobs
105 : * the engine step is one way to pass events back, PushFinishedJobs another
106 : * @param L The Lua stack
107 : * @param errorhandler Stack index of the Lua error handler
108 : */
109 : void step(lua_State *L, int errorhandler);
110 :
111 : /**
112 : * Push a list of finished jobs onto the stack
113 : * @param L The Lua stack
114 : */
115 : void pushFinishedJobs(lua_State *L);
116 :
117 : protected:
118 : /**
119 : * Get a Job from queue to be processed
120 : * this function blocks until a job is ready
121 : * @return a job to be processed
122 : */
123 : LuaJobInfo getJob();
124 :
125 : /**
126 : * Put a Job result back to result queue
127 : * @param result result of completed job
128 : */
129 : void putJobResult(LuaJobInfo result);
130 :
131 : /**
132 : * Initialize environment with current registred functions
133 : * this function adds all functions registred by registerFunction to the
134 : * passed lua stack
135 : * @param L Lua stack to initialize
136 : * @param top Stack position
137 : */
138 : void prepareEnvironment(lua_State* L, int top);
139 :
140 : private:
141 : // Variable locking the engine against further modification
142 : bool initDone;
143 :
144 : // Internal store for registred functions
145 : std::map<std::string, lua_CFunction> functionList;
146 :
147 : // Internal counter to create job IDs
148 : unsigned int jobIdCounter;
149 :
150 : // Mutex to protect job queue
151 : JMutex jobQueueMutex;
152 :
153 : // Job queue
154 : std::deque<LuaJobInfo> jobQueue;
155 :
156 : // Mutex to protect result queue
157 : JMutex resultQueueMutex;
158 : // Result queue
159 : std::deque<LuaJobInfo> resultQueue;
160 :
161 : // List of current worker threads
162 : std::vector<AsyncWorkerThread*> workerThreads;
163 :
164 : // Counter semaphore for job dispatching
165 : JSemaphore jobQueueCounter;
166 : };
167 :
168 : #endif // CPP_API_ASYNC_EVENTS_HEADER
|