ofs | hex dump | ascii |
---|
0000 | 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 00 00 00 01 00 08 06 00 00 00 5c 72 a8 | .PNG........IHDR.............\r. |
0020 | 66 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 bd a7 93 00 00 00 09 70 48 59 73 00 00 0e c3 00 | f....bKGD..............pHYs..... |
0040 | 00 0e c3 01 c7 6f a8 64 00 00 00 07 74 49 4d 45 07 e0 06 09 13 18 0e 53 1b a3 7f 00 00 20 00 49 | .....o.d....tIME.......S.......I |
0060 | 44 41 54 78 da ec bd 4d ac 6d db 72 1e f4 55 8d 31 e7 5a fb fc dc 7b 7d fd 8c e4 bc 98 07 09 56 | DATx...M.m.r..U.1.Z...{}.......V |
0080 | 6c 0c 92 11 e1 4f 51 08 72 1c c4 af 68 20 e8 d1 02 a4 80 e8 20 24 3a e9 44 56 40 22 12 a2 41 83 | l....OQ.r...h........$:.DV@"..A. |
00a0 | 0e 4d 24 24 7a a1 85 84 13 09 a1 88 58 a4 81 11 11 18 84 15 c5 8e 6d c5 ef dd 9f 73 f6 cf 9a 73 | .M$$z.......X.........m....s...s |
00c0 | 8c aa a2 51 63 8c 39 e6 dc 6b 9f 73 8d ec 7d 7d ce 1d f5 b4 df de 77 ef 75 d6 cf 9c 63 d4 a8 fa | ...Qc.9..k.s..}}......w.u...c... |
00e0 | ea ab af 80 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 | ....a....6l..a....6l..a....6l..a |
0100 | c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 | ....6l..a....6l..a....6l..a....6 |
0120 | 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 | l..a....6l..a....6l..a....6l..a. |
0140 | 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c | ...6l..a....6l..a....6l..a....6l |
0160 | d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 | ..a....6l..a....6l..a....6l..a.. |
0180 | 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 | ..6l..a....6l..a....6l..a....6l. |
01a0 | b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d | .a....6l..a....6l..a....6l..a... |
01c0 | 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 | .6l..a....6l..a....6l..a....6l.. |
01e0 | 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 6c d8 b0 61 c3 86 0d 1b 36 ec f7 db e8 bb f2 41 ff | a....6l..a....6l..a....6......A. |
0200 | cc 3f fb a7 e9 77 7f f8 23 bc 7c f9 12 2f 5f be c4 67 9f 7d 86 1f fc e0 07 78 fd fa 35 98 19 b7 | .?...w..#.|../_..g.}.....x..5... |
0220 | b7 b7 58 d7 15 66 06 22 82 aa 22 84 80 79 9e 01 00 77 77 77 f8 cd df fc 4d 7c f5 d5 57 b8 bd bb | ..X..f.".."..y...www....M|..W... |
0240 | c3 db 37 77 78 f5 ea 8c 57 f3 8c bf fe bf fe 4d 1b 4b e9 79 ed 67 7f e6 4f d0 ba ae 58 53 c6 67 | ..7wx...W......M.K.y.g..O...XS.g |
0260 | 9f 7d 86 d7 af 5f e3 f3 cf 3f c7 0f 7e f0 03 7c fa e9 a7 60 66 7c f9 e5 97 78 78 78 00 33 03 00 | .}..._...?..~..|...`f|...xxx.3.. |
0280 | 98 19 a7 d3 09 9f 7d f6 19 54 15 5f 7c f1 05 7e fd d7 7f 1d 77 77 77 f8 ea ab af b0 ae 2b 3e ff | ......}..T._|..~....www......+>. |
02a0 | fc c7 f0 37 fe c6 af 7c 67 ee 67 fc d8 3f e0 3f ff e7 7e 91 cc 70 73 b9 3c 9c ea ef ea 82 38 fe | ...7...|g.g..?.?..~..ps.<.....8. |
02c0 | dc 1b 33 b7 af eb bf f7 ff 16 20 fd 33 ff c4 9f bc fb 5f 86 13 78 36 fb 47 7e ee 1f 26 00 2f 99 | ..3.........3....._..x6.G~..&./. |
02e0 | 79 ea 7f af aa 8f 7e ae f7 2b 84 d0 7e 4e 29 41 55 db f7 fa d8 fa fd cf fe d9 5f 58 88 e8 e1 97 | y.....~..+..~N)AU........._X.... |
0300 | 7f f9 af da 70 00 1f b8 99 ea 64 b0 7f cf cc fe f4 53 0e a0 5f 38 bf 57 07 a0 c0 ff 49 c0 5f 02 | ....p.....d......S.._8.W....I._. |
0320 | 70 37 b6 e6 f3 18 33 bf 00 f0 17 98 f9 67 ff ff 38 00 11 81 aa b6 ef 47 07 00 e0 7f 06 f0 5f 02 | p7....3......g..8......G......_. |
0340 | 58 87 03 f8 c0 4d 24 47 03 fe 94 a8 fc 6b 00 40 f4 74 d6 63 f6 cd 1c fe e1 19 fe 28 11 fe f2 70 | X....M$G.....k.@.t.c.......(...p |
0360 | 00 cf 9a b7 ce 06 fc 39 00 ff f8 37 fe 37 44 bb 7b ff 9e 7b ad 30 fb af 86 03 f8 08 ec b2 5c 0c | .......9...7.7D.{..{.0........\. |
0380 | c0 97 39 e7 b6 08 8e 8b a1 2e 88 ba 28 fa bf 11 51 c3 05 f6 ff b6 fd fc 43 62 e8 d8 96 cf ea 00 | ..9.........(...Q.......Cb...... |
03a0 | 14 44 3f 6c f7 ee ca 7d bc 76 cf 98 b9 dd cf fe 7e 1f ef 3f 80 2f bf f1 69 30 1c c0 1f 6e 4b 29 | .D?l...}.v......~..?./..i0...nK) |
03c0 | 03 50 88 18 98 7d 11 98 59 0b fd fa 10 f0 9a 43 e8 c3 c3 fe ab 3d 87 29 6c 64 ff cf 6a aa 0a eb | .P...}..Y......C.....=.)ld..j... |
03e0 | 1c 33 1f 4e f6 7a 7f 8e 27 7f 7b 7c 49 fb 7a c7 50 bf 9a f3 7f 02 1b 1a 0e e0 03 b3 9c 53 c1 02 | .3.N.z..'.{|I.z.P............S.. |
0400 | 6c b7 10 cc 0c 22 02 11 b9 7a 1a f4 9b be fe 9c 73 46 ce b9 fd 9b f6 f7 71 fe 3f af 03 30 83 75 | l...."...z......sF......q.?..0.u |
0420 | 27 7f 7f ca 1f 1d fa 53 0e 20 84 80 10 02 62 8c 0d 1f 20 22 a0 ff 1a 0e e0 63 88 00 92 07 8d 44 | '......S......b....".....c.....D |
0440 | 60 8e 8f 4e 78 11 b9 9a 0e 1c 4f 93 7e c3 8b e8 2e c4 dc 07 a1 c3 fe c0 53 80 72 3a 1f 53 b5 2b | `..Nx.....O.~...........S.r:.S.+ |
0460 | a1 fc 55 cc 87 88 9a 03 e8 c1 c1 fa 58 22 fa ce d4 c7 bf 03 0e 40 da a2 99 a6 70 f5 31 d7 d2 bd | ..U.........X".......@....p.1... |
0480 | 63 9e b8 7f 8c ff 3e c6 88 79 9e bf 2b 87 c5 1f 9e 45 3b 4d 50 d5 92 ce ed 37 fa 35 a7 f0 be ff | c.....>..y..+....E;MP....7.5.... |
04a0 | de 61 05 f0 cd 4f 23 02 f8 38 2c 04 6e d0 91 99 42 0f b9 e1 71 11 1c 4f 91 10 c2 a3 bf 77 2b 08 | .a...O#..8,.n...B...q..O.....w+. |
04c0 | 44 0c e2 e1 01 9e db b6 f2 ac ed 72 f9 e3 06 af 5f bd 43 ef bf fa 08 cf 1f a7 50 51 10 db 70 00 | D..........r...._.C.......PQ..p. |
04e0 | 1f 83 9d 4e 27 00 06 11 45 ce 0a 1c d0 61 ee c2 c9 0a 0e f5 0b 22 84 b0 fb 7e 8c 12 d4 0c 3c 32 | ...N'...E....a......."...~....<2 |
0500 | 80 6f c5 dc 49 db 0e c8 3b 3a 80 fe 77 35 6a 38 02 bb 15 d3 01 00 11 41 ca eb 77 26 ad fb 0e 38 | .o..I...;:..w5j8.......A..w&...8 |
0520 | 80 19 66 86 75 4d 58 d7 fc 38 e4 bb 12 06 f6 08 72 cd 0d ab 03 d8 45 0a 62 65 f1 8c 08 e0 db d9 | ..f.uMX..8......r.....E.be...... |
0540 | fc d8 a5 00 c7 28 ed 18 d5 f5 df 9f aa 02 e5 bc 62 59 be 3b 1e fd a3 77 00 aa 54 72 74 82 c1 9e | .....(./*
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.
*/
#include <cstdio>
#include <cstdlib>
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "server.h"
#include "s_async.h"
#include "log.h"
#include "filesys.h"
#include "porting.h"
#include "common/c_internal.h"
/******************************************************************************/
AsyncEngine::~AsyncEngine()
{
// Request all threads to stop
for (AsyncWorkerThread *workerThread : workerThreads) {
workerThread->stop();
}
// Wake up all threads
for (std::vector<AsyncWorkerThread *>::iterator it = workerThreads.begin();
it != workerThreads.end(); ++it) {
jobQueueCounter.post();
}
// Wait for threads to finish
for (AsyncWorkerThread *workerThread : workerThreads) {
workerThread->wait();
}
// Force kill all threads
for (AsyncWorkerThread *workerThread : workerThreads) {
delete workerThread;
}
jobQueueMutex.lock();
jobQueue.clear();
jobQueueMutex.unlock();
workerThreads.clear();
}
/******************************************************************************/
void AsyncEngine::registerStateInitializer(StateInitializer func)
{
stateInitializers.push_back(func);
}
/******************************************************************************/
void AsyncEngine::initialize(unsigned int numEngines)
{
initDone = true;
for (unsigned int i = 0; i < numEngines; i++) {
AsyncWorkerThread *toAdd = new AsyncWorkerThread(this,
std::string("AsyncWorker-") + itos(i));
workerThreads.push_back(toAdd);
toAdd->start();
}
}
/******************************************************************************/
unsigned int AsyncEngine::queueAsyncJob(const std::string &func,
const std::string ¶ms)
{
jobQueueMutex.lock();
LuaJobInfo toAdd;
toAdd.id = jobIdCounter++;
toAdd.serializedFunction = func;
toAdd.serializedParams = params;
jobQueue.push_back(toAdd);
jobQueueCounter.post();
jobQueueMutex.unlock();
return toAdd.id;
}
/******************************************************************************/
LuaJobInfo AsyncEngine::getJob()
{
jobQueueCounter.wait();
jobQueueMutex.lock();
LuaJobInfo retval;
if (!jobQueue.empty()) {
retval = jobQueue.front();
jobQueue.pop_front();
retval.valid = true;
}
jobQueueMutex.unlock();
return retval;
}
/******************************************************************************/
void AsyncEngine::putJobResult(const LuaJobInfo &result)
{
resultQueueMutex.lock();
resultQueue.push_back(result);
resultQueueMutex.unlock();
}
/******************************************************************************/
void AsyncEngine::step(lua_State *L)
{
int error_handler = PUSH_ERROR_HANDLER(L);
lua_getglobal(L, "core");
resultQueueMutex.lock();
while (!resultQueue.empty()) {
LuaJobInfo jobDone = resultQueue.front();
resultQueue.pop_front();
lua_getfield(L, -1, "async_event_handler");
if (lua_isnil(L, -1)) {
FATAL_ERROR("Async event handler does not exist!");
}
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushinteger(L, jobDone.id);
lua_pushlstring(L, jobDone.serializedResult.data(),
jobDone.serializedResult.size());
PCALL_RESL(L, lua_pcall(L, 2, 0, error_handler));
}
resultQueueMutex.unlock();
lua_pop(L, 2); // Pop core and error handler
}
/******************************************************************************/
void AsyncEngine::pushFinishedJobs(lua_State* L) {
// Result Table
MutexAutoLock l(resultQueueMutex);
unsigned int index = 1;
lua_createtable(L, resultQueue.size(), 0);
int top = lua_gettop(L);
while (!resultQueue.empty()) {
LuaJobInfo jobDone = resultQueue.front();
resultQueue.pop_front();
lua_createtable(L, 0, 2); // Pre-allocate space for two map fields
int top_lvl2 = lua_gettop(L);
lua_pushstring(L, "jobid");
lua_pushnumber(L, jobDone.id);
lua_settable(L, top_lvl2);
lua_pushstring(L, "retval");
lua_pushlstring(L, jobDone.serializedResult.data(),
jobDone.serializedResult.size());
lua_settable(L, top_lvl2);
lua_rawseti(L, top, index++);
}
}
/******************************************************************************/
void AsyncEngine::prepareEnvironment(lua_State* L, int top)
{
for (StateInitializer &stateInitializer : stateInitializers) {
stateInitializer(L, top);
}
}
/******************************************************************************/
AsyncWorkerThread::AsyncWorkerThread(AsyncEngine* jobDispatcher,
const std::string &name) :
Thread(name),
ScriptApiBase(ScriptingType::Async),
jobDispatcher(jobDispatcher)
{
lua_State *L = getStack();
// Prepare job lua environment
lua_getglobal(L, "core");
int top = lua_gettop(L);
// Push builtin initialization type
lua_pushstring(L, "async");
lua_setglobal(L, "INIT");
jobDispatcher->prepareEnvironment(L, top);
}
/******************************************************************************/
AsyncWorkerThread::~AsyncWorkerThread()
{
sanity_check(!isRunning());
}
/******************************************************************************/
void* AsyncWorkerThread::run()
{
lua_State *L = getStack();
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");
}
int error_handler = PUSH_ERROR_HANDLER(L);
lua_getglobal(L, "core");
if (lua_isnil(L, -1)) {
FATAL_ERROR("Unable to find core within async environment!");
}
// Main loop
while (!stopRequested()) {
// Wait for job
LuaJobInfo toProcess = jobDispatcher->getJob();
if (!toProcess.valid || stopRequested()) {
continue;
}
lua_getfield(L, -1, "job_processor");
if (lua_isnil(L, -1)) {
FATAL_ERROR("Unable to get async job processor!");
}
luaL_checktype(L, -1, LUA_TFUNCTION);
// Call it
lua_pushlstring(L,
toProcess.serializedFunction.data(),
toProcess.serializedFunction.size());
lua_pushlstring(L,
toProcess.serializedParams.data(),
toProcess.serializedParams.size());
int result = lua_pcall(L, 2, 1, error_handler);
if (result) {
PCALL_RES(result);
toProcess.serializedResult = "";
} else {
// Fetch result
size_t length;
const char *retval = lua_tolstring(L, -1, &length);
toProcess.serializedResult = std::string(retval, length);
}
lua_pop(L, 1); // Pop retval
// Put job result
jobDispatcher->putJobResult(toProcess);
}
lua_pop(L, 2); // Pop core and error handler
return 0;
}
|