s_async.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. Minetest
  3. Copyright (C) 2013 sapier, <sapier AT gmx DOT net>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #pragma once
  17. #include <vector>
  18. #include <deque>
  19. #include <map>
  20. #include "threading/semaphore.h"
  21. #include "threading/thread.h"
  22. #include "lua.h"
  23. #include "cpp_api/s_base.h"
  24. // Forward declarations
  25. class AsyncEngine;
  26. // Declarations
  27. // Data required to queue a job
  28. struct LuaJobInfo
  29. {
  30. LuaJobInfo() = default;
  31. // Function to be called in async environment
  32. std::string serializedFunction = "";
  33. // Parameter to be passed to function
  34. std::string serializedParams = "";
  35. // Result of function call
  36. std::string serializedResult = "";
  37. // JobID used to identify a job and match it to callback
  38. unsigned int id = 0;
  39. bool valid = false;
  40. };
  41. // Asynchronous working environment
  42. class AsyncWorkerThread : public Thread, public ScriptApiBase {
  43. public:
  44. AsyncWorkerThread(AsyncEngine* jobDispatcher, const std::string &name);
  45. virtual ~AsyncWorkerThread();
  46. void *run();
  47. private:
  48. AsyncEngine *jobDispatcher = nullptr;
  49. };
  50. // Asynchornous thread and job management
  51. class AsyncEngine {
  52. friend class AsyncWorkerThread;
  53. typedef void (*StateInitializer)(lua_State *L, int top);
  54. public:
  55. AsyncEngine() = default;
  56. ~AsyncEngine();
  57. /**
  58. * Register function to be called on new states
  59. * @param func C function to be called
  60. */
  61. void registerStateInitializer(StateInitializer func);
  62. /**
  63. * Create async engine tasks and lock function registration
  64. * @param numEngines Number of async threads to be started
  65. */
  66. void initialize(unsigned int numEngines);
  67. /**
  68. * Queue an async job
  69. * @param func Serialized lua function
  70. * @param params Serialized parameters
  71. * @return jobid The job is queued
  72. */
  73. unsigned int queueAsyncJob(const std::string &func, const std::string &params);
  74. /**
  75. * Engine step to process finished jobs
  76. * the engine step is one way to pass events back, PushFinishedJobs another
  77. * @param L The Lua stack
  78. */
  79. void step(lua_State *L);
  80. /**
  81. * Push a list of finished jobs onto the stack
  82. * @param L The Lua stack
  83. */
  84. void pushFinishedJobs(lua_State *L);
  85. protected:
  86. /**
  87. * Get a Job from queue to be processed
  88. * this function blocks until a job is ready
  89. * @return a job to be processed
  90. */
  91. LuaJobInfo getJob();
  92. /**
  93. * Put a Job result back to result queue
  94. * @param result result of completed job
  95. */
  96. void putJobResult(const LuaJobInfo &result);
  97. /**
  98. * Initialize environment with current registred functions
  99. * this function adds all functions registred by registerFunction to the
  100. * passed lua stack
  101. * @param L Lua stack to initialize
  102. * @param top Stack position
  103. */
  104. void prepareEnvironment(lua_State* L, int top);
  105. private:
  106. // Variable locking the engine against further modification
  107. bool initDone = false;
  108. // Internal store for registred state initializers
  109. std::vector<StateInitializer> stateInitializers;
  110. // Internal counter to create job IDs
  111. unsigned int jobIdCounter = 0;
  112. // Mutex to protect job queue
  113. std::mutex jobQueueMutex;
  114. // Job queue
  115. std::deque<LuaJobInfo> jobQueue;
  116. // Mutex to protect result queue
  117. std::mutex resultQueueMutex;
  118. // Result queue
  119. std::deque<LuaJobInfo> resultQueue;
  120. // List of current worker threads
  121. std::vector<AsyncWorkerThread*> workerThreads;
  122. // Counter semaphore for job dispatching
  123. Semaphore jobQueueCounter;
  124. };