diff options
Diffstat (limited to '')
-rw-r--r-- | src/lua/lua_thread_pool.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/lua/lua_thread_pool.h b/src/lua/lua_thread_pool.h new file mode 100644 index 0000000..b612ac3 --- /dev/null +++ b/src/lua/lua_thread_pool.h @@ -0,0 +1,194 @@ +#ifndef LUA_THREAD_POOL_H_ +#define LUA_THREAD_POOL_H_ + +#include <lua.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct thread_entry; +struct lua_thread_pool; + +typedef void (*lua_thread_finish_t)(struct thread_entry *thread, int ret); + +typedef void (*lua_thread_error_t)(struct thread_entry *thread, int ret, const char *msg); + +struct thread_entry { + lua_State *lua_state; + gint thread_index; + gpointer cd; + + /* function to handle result of called method, can be NULL */ + lua_thread_finish_t finish_callback; + + /* function to log result, i.e. if you want to modify error logging message or somehow process this state, can be NUL */ + lua_thread_error_t error_callback; + struct rspamd_task *task; + struct rspamd_config *cfg; +}; + +struct lua_callback_state { + lua_State *L; + struct thread_entry *my_thread; + struct thread_entry *previous_thread; + struct lua_thread_pool *thread_pool; +}; + +/** + * Allocates new thread pool on state L. Pre-creates number of lua-threads to use later on + * + * @param L + * @return + */ +struct lua_thread_pool * +lua_thread_pool_new(lua_State *L); + +/** + * Destroys the pool + * @param pool + */ +void lua_thread_pool_free(struct lua_thread_pool *pool); + +/** + * Extracts a thread from the list of available ones. + * It immediately becomes the running one and should be used to run a Lua script/function straight away. + * as soon as the code is finished, it should be either returned into list of available threads by + * calling lua_thread_pool_return() or terminated by calling lua_thread_pool_terminate_entry() + * if the code finished with error. + * + * If the code performed YIELD, the thread is still running and it's live should be controlled by the callee + * + * @param task + * @return + */ +struct thread_entry * +lua_thread_pool_get_for_task(struct rspamd_task *task); + +/** + * The same, but used when task is not available + * + * @param cfg + * @return + */ +struct thread_entry * +lua_thread_pool_get_for_config(struct rspamd_config *cfg); + +/** + * Return thread into the list of available ones. It can't be done with yielded or dead threads. + * + * @param pool + * @param thread_entry + */ +void lua_thread_pool_return_full(struct lua_thread_pool *pool, + struct thread_entry *thread_entry, + const gchar *loc); + +#define lua_thread_pool_return(pool, thread_entry) \ + lua_thread_pool_return_full(pool, thread_entry, G_STRLOC) + +/** + * Currently running thread. Typically needed in yielding point - to fill-up continuation. + * + * @param pool + * @return + */ +struct thread_entry * +lua_thread_pool_get_running_entry_full(struct lua_thread_pool *pool, + const gchar *loc); + +#define lua_thread_pool_get_running_entry(pool) \ + lua_thread_pool_get_running_entry_full(pool, G_STRLOC) + +/** + * Updates currently running thread + * + * @param pool + * @param thread_entry + */ +void lua_thread_pool_set_running_entry_full(struct lua_thread_pool *pool, + struct thread_entry *thread_entry, + const gchar *loc); + +#define lua_thread_pool_set_running_entry(pool, thread_entry) \ + lua_thread_pool_set_running_entry_full(pool, thread_entry, G_STRLOC) + +/** + * Prevents yielded thread to be used for callback execution. lua_thread_pool_restore_callback() should be called afterwards. + * + * @param pool + * @param cbs + */ +void lua_thread_pool_prepare_callback_full(struct lua_thread_pool *pool, + struct lua_callback_state *cbs, const gchar *loc); + +#define lua_thread_pool_prepare_callback(pool, cbs) \ + lua_thread_pool_prepare_callback_full(pool, cbs, G_STRLOC) + +/** + * Restores state after lua_thread_pool_prepare_callback () usage + * + * @param cbs + */ +void lua_thread_pool_restore_callback_full(struct lua_callback_state *cbs, + const gchar *loc); + +#define lua_thread_pool_restore_callback(cbs) \ + lua_thread_pool_restore_callback_full(cbs, G_STRLOC) + +/** + * Acts like lua_call but the tread is able to suspend execution. + * As soon as the call is over, call either thread_entry::finish_callback or thread_entry::error_callback. + * + * @param thread_entry + * @param narg + */ +void lua_thread_call_full(struct thread_entry *thread_entry, + int narg, + const gchar *loc); + +#define lua_thread_call(thread_entry, narg) \ + lua_thread_call_full(thread_entry, narg, G_STRLOC) + +/** + * Yields thread. should be only called in return statement + * @param thread_entry + * @param nresults + * @return + */ +int lua_thread_yield_full(struct thread_entry *thread_entry, int nresults, + const gchar *loc); + +#define lua_thread_yield(thread_entry, narg) \ + lua_thread_yield_full(thread_entry, narg, G_STRLOC) + +/** + * Resumes suspended by lua_yield_thread () thread + * @param task + * @param thread_entry + * @param narg + */ +void lua_thread_resume_full(struct thread_entry *thread_entry, + int narg, + const gchar *loc); + +#define lua_thread_resume(thread_entry, narg) \ + lua_thread_resume_full(thread_entry, narg, G_STRLOC) + +/** + * Terminates thread pool entry and fill the pool with another thread entry if needed + * @param pool + * @param thread_entry + * @param loc + */ +void lua_thread_pool_terminate_entry_full(struct lua_thread_pool *pool, + struct thread_entry *thread_entry, + const gchar *loc, bool enforce); +#define lua_thread_pool_terminate_entry(pool, thread_entry) \ + lua_thread_pool_terminate_entry_full(pool, thread_entry, G_STRLOC, false) + +#ifdef __cplusplus +} +#endif + +#endif /* LUA_THREAD_POOL_H_ */ |