]> 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 de1ebc07b7faf22f52e148b1167da63c232e7714..1fb84fab66e7c83fe19dd8f1a1e7b760ad9c7e21 100644 (file)
@@ -47,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();
 }
 
@@ -82,6 +81,7 @@ bool AsyncEngine::registerFunction(const char* name, lua_CFunction func)
        if (initDone) {
                return false;
        }
+
        functionList[name] = func;
        return true;
 }
@@ -92,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;
@@ -109,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;
 }
@@ -119,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;
@@ -130,7 +131,7 @@ LuaJobInfo AsyncEngine::getJob()
                jobQueue.pop_front();
                retval.valid = true;
        }
-       jobQueueMutex.Unlock();
+       jobQueueMutex.unlock();
 
        return retval;
 }
@@ -138,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)
 {
+       int error_handler = PUSH_ERROR_HANDLER(L);
        lua_getglobal(L, "core");
-       resultQueueMutex.Lock();
+       resultQueueMutex.lock();
        while (!resultQueue.empty()) {
                LuaJobInfo jobDone = resultQueue.front();
                resultQueue.pop_front();
@@ -155,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);
@@ -164,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 core
+       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);
@@ -199,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);
@@ -216,10 +214,10 @@ 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();
 
@@ -237,50 +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), "%u", threadnum);
-       log_register_thread(std::string("AsyncWorkerThread_") + number);
-
-       porting::setThreadName((std::string("AsyncWorkTh_") + number).c_str());
-
        lua_State *L = getStack();
 
        std::string script = getServer()->getBuiltinLuaPath() + DIR_DELIM + "init.lua";
-       if (!loadScript(script)) {
-               errorstream
-                       << "AsyncWorkderThread execution of async base environment failed!"
-                       << std::endl;
-               abort();
+       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");
        }
 
+       int error_handler = PUSH_ERROR_HANDLER(L);
+
        lua_getglobal(L, "core");
        if (lua_isnil(L, -1)) {
-               errorstream << "Unable to find core within async environment!";
-               abort();
+               FATAL_ERROR("Unable to find core within async environment!");
        }
 
        // 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_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);
@@ -293,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
@@ -309,9 +300,7 @@ void* AsyncWorkerThread::Thread()
                jobDispatcher->putJobResult(toProcess);
        }
 
-       lua_pop(L, 1);  // Pop core
-
-       log_deregister_thread();
+       lua_pop(L, 2);  // Pop core and error handler
 
        return 0;
 }