aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_async_events.h
diff options
context:
space:
mode:
authorsapier <Sapier at GMX dot net>2013-11-26 18:15:31 +0100
committersapier <Sapier at GMX dot net>2013-11-29 22:09:14 +0100
commit2e66aca35722e7fee786027d545fe371786fc01f (patch)
treef6d3ec721d23680bb493bd66054379b9327a1c7a /src/script/lua_api/l_async_events.h
parentb08d7558de53325d184b3ddf0476cb84fc08d0ad (diff)
downloadminetest-2e66aca35722e7fee786027d545fe371786fc01f.tar.gz
minetest-2e66aca35722e7fee786027d545fe371786fc01f.tar.bz2
minetest-2e66aca35722e7fee786027d545fe371786fc01f.zip
Fix modstore/favourites hang by adding asynchronous lua job support
Diffstat (limited to 'src/script/lua_api/l_async_events.h')
-rw-r--r--src/script/lua_api/l_async_events.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/script/lua_api/l_async_events.h b/src/script/lua_api/l_async_events.h
new file mode 100644
index 000000000..4aaf3bdfe
--- /dev/null
+++ b/src/script/lua_api/l_async_events.h
@@ -0,0 +1,228 @@
+/*
+Minetest
+Copyright (C) 2013 sapier, <sapier AT gmx DOT net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef C_ASYNC_EVENTS_H_
+#define C_ASYNC_EVENTS_H_
+
+#include <vector>
+#include <map>
+#include <unistd.h>
+
+/******************************************************************************/
+/* Includes */
+/******************************************************************************/
+#include "jthread/jthread.h"
+#include "jthread/jmutex.h"
+#include "jthread/jsemaphore.h"
+#include "debug.h"
+#include "lua.h"
+
+/******************************************************************************/
+/* Typedefs and macros */
+/******************************************************************************/
+#define MAINMENU_NUMBER_OF_ASYNC_THREADS 4
+
+/******************************************************************************/
+/* forward declarations */
+/******************************************************************************/
+class AsyncEngine;
+
+/******************************************************************************/
+/* declarations */
+/******************************************************************************/
+
+/** a struct to encapsulate data required to queue a job **/
+struct LuaJobInfo {
+ /** function to be called in async environment **/
+ std::string serializedFunction;
+ /** parameter table to be passed to function **/
+ std::string serializedParams;
+ /** result of function call **/
+ std::string serializedResult;
+ /** jobid used to identify a job and match it to callback **/
+ unsigned int JobId;
+};
+
+/** class encapsulating a asynchronous working environment **/
+class AsyncWorkerThread : public JThread {
+public:
+ /**
+ * default constructor
+ * @param pointer to job dispatcher
+ */
+ AsyncWorkerThread(AsyncEngine* jobdispatcher, unsigned int threadnumber);
+
+ /**
+ * default destructor
+ */
+ virtual ~AsyncWorkerThread();
+
+ /**
+ * thread function
+ */
+ void* Thread() {
+ ThreadStarted();
+ return worker_thread_wrapper(this);
+ }
+
+ /**
+ * wait for thread to stop
+ */
+ void Wait() {
+ while(IsRunning()) {
+ sleep(1);
+ }
+ }
+
+private:
+ /**
+ * helper function to run a lua script
+ * @param path of script
+ */
+ bool runScript(std::string script);
+
+ /**
+ * main function of thread
+ */
+ void* worker_thread_main();
+
+ /**
+ * static wrapper for thread creation
+ * @param this pointer to the thread to be created
+ */
+ static void* worker_thread_wrapper(void* thread);
+
+ /**
+ * pointer to job dispatcher
+ */
+ AsyncEngine* m_JobDispatcher;
+
+ /**
+ * the lua stack to run at
+ */
+ lua_State* m_LuaStack;
+
+ /**
+ * lua internal stack number of error handler
+ */
+ int m_luaerrorhandler;
+
+ /**
+ * thread number used for debug output
+ */
+ unsigned int m_threadnum;
+
+};
+
+/** asynchornous thread and job management **/
+class AsyncEngine {
+ friend AsyncWorkerThread;
+public:
+ /**
+ * default constructor
+ */
+ AsyncEngine();
+ /**
+ * default destructor
+ */
+ ~AsyncEngine();
+
+ /**
+ * register function to be used within engines
+ * @param name function name to be used within lua environment
+ * @param fct c-function to be called
+ */
+ bool registerFunction(const char* name, lua_CFunction fct);
+
+ /**
+ * create async engine tasks and lock function registration
+ * @param numengines number of async threads to be started
+ */
+ void Initialize(unsigned int numengines);
+
+ /**
+ * queue/run a async job
+ * @param fct serialized lua function
+ * @param params serialized parameters
+ * @return jobid the job is queued
+ */
+ unsigned int doAsyncJob(std::string fct, std::string params);
+
+ /**
+ * engine step to process finished jobs
+ * the engine step is one way to pass events back, PushFinishedJobs another
+ * @param L the lua environment to do the step in
+ */
+ void Step(lua_State *L);
+
+
+ void PushFinishedJobs(lua_State* L);
+
+protected:
+ /**
+ * Get a Job from queue to be processed
+ * this function blocks until a job is ready
+ * @return a job to be processed
+ */
+ LuaJobInfo getJob();
+
+ /**
+ * put a Job result back to result queue
+ * @param result result of completed job
+ */
+ void putJobResult(LuaJobInfo result);
+
+ /**
+ * initialize environment with current registred functions
+ * this function adds all functions registred by registerFunction to the
+ * passed lua stack
+ * @param L lua stack to initialize
+ * @param top stack position
+ */
+ void PrepareEnvironment(lua_State* L, int top);
+
+private:
+
+ /** variable locking the engine against further modification **/
+ bool m_initDone;
+
+ /** internal store for registred functions **/
+ std::map<std::string,lua_CFunction> m_FunctionList;
+
+ /** internal counter to create job id's **/
+ unsigned int m_JobIdCounter;
+
+ /** mutex to protect job queue **/
+ JMutex m_JobQueueMutex;
+ /** job queue **/
+ std::vector<LuaJobInfo> m_JobQueue;
+
+ /** mutext to protect result queue **/
+ JMutex m_ResultQueueMutex;
+ /** result queue **/
+ std::vector<LuaJobInfo> m_ResultQueue;
+
+ /** list of current worker threads **/
+ std::vector<AsyncWorkerThread*> m_WorkerThreads;
+
+ /** counter semaphore for job dispatching **/
+ JSemaphore m_JobQueueCounter;
+};
+
+#endif /* C_ASYNC_EVENTS_H_ */