]> git.lizzy.rs Git - minetest.git/blobdiff - src/script/cpp_api/s_async.cpp
[CSM] Add core.get_timeofday & core.get_day_count env calls (#5401)
[minetest.git] / src / script / cpp_api / s_async.cpp
index 4feed3e5652a4595691dacb86fa96b81ab915f96..1fb84fab66e7c83fe19dd8f1a1e7b760ad9c7e21 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 #include "lualib.h"
 }
 
+#include "server.h"
 #include "s_async.h"
 #include "log.h"
 #include "filesys.h"
@@ -46,32 +47,31 @@ AsyncEngine::~AsyncEngine()
        // Request all threads to stop
        for (std::vector<AsyncWorkerThread *>::iterator it = workerThreads.begin();
                        it != workerThreads.end(); it++) {
-               (*it)->Stop();
+               (*it)->stop();
        }
 
 
        // Wake up all threads
        for (std::vector<AsyncWorkerThread *>::iterator it = workerThreads.begin();
                        it != workerThreads.end(); it++) {
-               jobQueueCounter.Post();
+               jobQueueCounter.post();
        }
 
        // Wait for threads to finish
        for (std::vector<AsyncWorkerThread *>::iterator it = workerThreads.begin();
                        it != workerThreads.end(); it++) {
-               (*it)->Wait();
+               (*it)->wait();
        }
 
        // Force kill all threads
        for (std::vector<AsyncWorkerThread *>::iterator it = workerThreads.begin();
                        it != workerThreads.end(); it++) {
-               (*it)->Kill();
                delete *it;
        }
 
-       jobQueueMutex.Lock();
+       jobQueueMutex.lock();
        jobQueue.clear();
-       jobQueueMutex.Unlock();
+       jobQueueMutex.unlock();
        workerThreads.clear();
 }
 
@@ -81,6 +81,7 @@ bool AsyncEngine::registerFunction(const char* name, lua_CFunction func)
        if (initDone) {
                return false;
        }
+
        functionList[name] = func;
        return true;
 }
@@ -91,16 +92,17 @@ void AsyncEngine::initialize(unsigned int numEngines)
        initDone = true;
 
        for (unsigned int i = 0; i < numEngines; i++) {
-               AsyncWorkerThread *toAdd = new AsyncWorkerThread(this, i);
+               AsyncWorkerThread *toAdd = new AsyncWorkerThread(this,
+                       std::string("AsyncWorker-") + itos(i));
                workerThreads.push_back(toAdd);
-               toAdd->Start();
+               toAdd->start();
        }
 }
 
 /******************************************************************************/
 unsigned int AsyncEngine::queueAsyncJob(std::string func, std::string params)
 {
-       jobQueueMutex.Lock();
+       jobQueueMutex.lock();
        LuaJobInfo toAdd;
        toAdd.id = jobIdCounter++;
        toAdd.serializedFunction = func;
@@ -108,9 +110,9 @@ unsigned int AsyncEngine::queueAsyncJob(std::string func, std::string params)
 
        jobQueue.push_back(toAdd);
 
-       jobQueueCounter.Post();
+       jobQueueCounter.post();
 
-       jobQueueMutex.Unlock();
+       jobQueueMutex.unlock();
 
        return toAdd.id;
 }
@@ -118,8 +120,8 @@ unsigned int AsyncEngine::queueAsyncJob(std::string func, std::string params)
 /******************************************************************************/
 LuaJobInfo AsyncEngine::getJob()
 {
-       jobQueueCounter.Wait();
-       jobQueueMutex.Lock();
+       jobQueueCounter.wait();
+       jobQueueMutex.lock();
 
        LuaJobInfo retval;
        retval.valid = false;
@@ -129,7 +131,7 @@ LuaJobInfo AsyncEngine::getJob()
                jobQueue.pop_front();
                retval.valid = true;
        }
-       jobQueueMutex.Unlock();
+       jobQueueMutex.unlock();
 
        return retval;
 }
@@ -137,16 +139,17 @@ LuaJobInfo AsyncEngine::getJob()
 /******************************************************************************/
 void AsyncEngine::putJobResult(LuaJobInfo result)
 {
-       resultQueueMutex.Lock();
+       resultQueueMutex.lock();
        resultQueue.push_back(result);
-       resultQueueMutex.Unlock();
+       resultQueueMutex.unlock();
 }
 
 /******************************************************************************/
-void AsyncEngine::step(lua_State *L, int errorhandler)
+void AsyncEngine::step(lua_State *L)
 {
-       lua_getglobal(L, "engine");
-       resultQueueMutex.Lock();
+       int error_handler = PUSH_ERROR_HANDLER(L);
+       lua_getglobal(L, "core");
+       resultQueueMutex.lock();
        while (!resultQueue.empty()) {
                LuaJobInfo jobDone = resultQueue.front();
                resultQueue.pop_front();
@@ -154,7 +157,7 @@ void AsyncEngine::step(lua_State *L, int errorhandler)
                lua_getfield(L, -1, "async_event_handler");
 
                if (lua_isnil(L, -1)) {
-                       assert("Async event handler does not exist!" == 0);
+                       FATAL_ERROR("Async event handler does not exist!");
                }
 
                luaL_checktype(L, -1, LUA_TFUNCTION);
@@ -163,18 +166,16 @@ void AsyncEngine::step(lua_State *L, int errorhandler)
                lua_pushlstring(L, jobDone.serializedResult.data(),
                                jobDone.serializedResult.size());
 
-               if (lua_pcall(L, 2, 0, errorhandler)) {
-                       script_error(L);
-               }
+               PCALL_RESL(L, lua_pcall(L, 2, 0, error_handler));
        }
-       resultQueueMutex.Unlock();
-       lua_pop(L, 1); // Pop engine
+       resultQueueMutex.unlock();
+       lua_pop(L, 2); // Pop core and error handler
 }
 
 /******************************************************************************/
 void AsyncEngine::pushFinishedJobs(lua_State* L) {
        // Result Table
-       resultQueueMutex.Lock();
+       MutexAutoLock l(resultQueueMutex);
 
        unsigned int index = 1;
        lua_createtable(L, resultQueue.size(), 0);
@@ -198,14 +199,12 @@ void AsyncEngine::pushFinishedJobs(lua_State* L) {
 
                lua_rawseti(L, top, index++);
        }
-
-       resultQueueMutex.Unlock();
 }
 
 /******************************************************************************/
 void AsyncEngine::prepareEnvironment(lua_State* L, int top)
 {
-       for (std::map<std::string, lua_CFunction>::iterator it = functionList.begin();
+       for (UNORDERED_MAP<std::string, lua_CFunction>::iterator it = functionList.begin();
                        it != functionList.end(); it++) {
                lua_pushstring(L, it->first.c_str());
                lua_pushcfunction(L, it->second);
@@ -215,27 +214,20 @@ void AsyncEngine::prepareEnvironment(lua_State* L, int top)
 
 /******************************************************************************/
 AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher,
-               unsigned int threadNum) :
+               const std::string &name) :
+       Thread(name),
        ScriptApiBase(),
-       jobDispatcher(jobDispatcher),
-       threadnum(threadNum)
+       jobDispatcher(jobDispatcher)
 {
        lua_State *L = getStack();
 
-       luaL_openlibs(L);
-
        // Prepare job lua environment
-       lua_newtable(L);
-       lua_setglobal(L, "engine");
-       lua_getglobal(L, "engine");
+       lua_getglobal(L, "core");
        int top = lua_gettop(L);
 
-       lua_pushstring(L, DIR_DELIM);
-       lua_setglobal(L, "DIR_DELIM");
-
-       lua_pushstring(L,
-                       (porting::path_share + DIR_DELIM + "builtin").c_str());
-       lua_setglobal(L, "SCRIPTDIR");
+       // Push builtin initialization type
+       lua_pushstring(L, "async");
+       lua_setglobal(L, "INIT");
 
        jobDispatcher->prepareEnvironment(L, top);
 }
@@ -243,51 +235,42 @@ AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher,
 /******************************************************************************/
 AsyncWorkerThread::~AsyncWorkerThread()
 {
-       assert(IsRunning() == false);
+       sanity_check(!isRunning());
 }
 
 /******************************************************************************/
-void* AsyncWorkerThread::Thread()
+void* AsyncWorkerThread::run()
 {
-       ThreadStarted();
-
-       // Register thread for error logging
-       char number[21];
-       snprintf(number, sizeof(number), "%d", threadnum);
-       log_register_thread(std::string("AsyncWorkerThread_") + number);
+       lua_State *L = getStack();
 
-       porting::setThreadName((std::string("AsyncWorkTh_") + number).c_str());
+       std::string script = getServer()->getBuiltinLuaPath() + DIR_DELIM + "init.lua";
+       try {
+               loadScript(script);
+       } catch (const ModError &e) {
+               errorstream << "Execution of async base environment failed: "
+                       << e.what() << std::endl;
+               FATAL_ERROR("Execution of async base environment failed");
+       }
 
-       std::string asyncscript = porting::path_share + DIR_DELIM + "builtin"
-                       + DIR_DELIM + "async_env.lua";
+       int error_handler = PUSH_ERROR_HANDLER(L);
 
-       if (!loadScript(asyncscript)) {
-               errorstream
-                       << "AsyncWorkderThread execution of async base environment failed!"
-                       << std::endl;
-               abort();
+       lua_getglobal(L, "core");
+       if (lua_isnil(L, -1)) {
+               FATAL_ERROR("Unable to find core within async environment!");
        }
 
-       lua_State *L = getStack();
        // Main loop
-       while (!StopRequested()) {
+       while (!stopRequested()) {
                // Wait for job
                LuaJobInfo toProcess = jobDispatcher->getJob();
 
-               if (toProcess.valid == false || StopRequested()) {
+               if (toProcess.valid == false || stopRequested()) {
                        continue;
                }
 
-               lua_getglobal(L, "engine");
-               if (lua_isnil(L, -1)) {
-                       errorstream << "Unable to find engine within async environment!";
-                       abort();
-               }
-
                lua_getfield(L, -1, "job_processor");
                if (lua_isnil(L, -1)) {
-                       errorstream << "Unable to get async job processor!" << std::endl;
-                       abort();
+                       FATAL_ERROR("Unable to get async job processor!");
                }
 
                luaL_checktype(L, -1, LUA_TFUNCTION);
@@ -300,8 +283,9 @@ void* AsyncWorkerThread::Thread()
                                toProcess.serializedParams.data(),
                                toProcess.serializedParams.size());
 
-               if (lua_pcall(L, 2, 1, m_errorhandler)) {
-                       scriptError();
+               int result = lua_pcall(L, 2, 1, error_handler);
+               if (result) {
+                       PCALL_RES(result);
                        toProcess.serializedResult = "";
                } else {
                        // Fetch result
@@ -310,13 +294,14 @@ void* AsyncWorkerThread::Thread()
                        toProcess.serializedResult = std::string(retval, length);
                }
 
-               // Pop engine, job_processor, and retval
-               lua_pop(L, 3);
+               lua_pop(L, 1);  // Pop retval
 
                // Put job result
                jobDispatcher->putJobResult(toProcess);
        }
-       log_deregister_thread();
+
+       lua_pop(L, 2);  // Pop core and error handler
+
        return 0;
 }