1 #ifndef LUA_THREAD_POOL_H_ 2 #define LUA_THREAD_POOL_H_ 3 4 #include <lua.h> 5 6 #ifdef __cplusplus 7 extern "C" { 8 #endif 9 10 struct thread_entry; 11 struct lua_thread_pool; 12 13 typedef void (*lua_thread_finish_t) (struct thread_entry *thread, int ret); 14 15 typedef void (*lua_thread_error_t) (struct thread_entry *thread, int ret, const char *msg); 16 17 struct thread_entry { 18 lua_State *lua_state; 19 gint thread_index; 20 gpointer cd; 21 22 /* function to handle result of called method, can be NULL */ 23 lua_thread_finish_t finish_callback; 24 25 /* function to log result, i.e. if you want to modify error logging message or somehow process this state, can be NUL */ 26 lua_thread_error_t error_callback; 27 struct rspamd_task *task; 28 struct rspamd_config *cfg; 29 }; 30 31 struct lua_callback_state { 32 lua_State *L; 33 struct thread_entry *my_thread; 34 struct thread_entry *previous_thread; 35 struct lua_thread_pool *thread_pool; 36 }; 37 38 /** 39 * Allocates new thread pool on state L. Pre-creates number of lua-threads to use later on 40 * 41 * @param L 42 * @return 43 */ 44 struct lua_thread_pool * 45 lua_thread_pool_new (lua_State *L); 46 47 /** 48 * Destroys the pool 49 * @param pool 50 */ 51 void 52 lua_thread_pool_free (struct lua_thread_pool *pool); 53 54 /** 55 * Extracts a thread from the list of available ones. 56 * It immediately becames running one and should be used to run a Lua script/function straight away. 57 * as soon as the code is finished, it should be either returned into list of available threads by 58 * calling lua_thread_pool_return() or terminated by calling lua_thread_pool_terminate_entry() 59 * if the code finished with error. 60 * 61 * If the code performed YIELD, the thread is still running and it's live should be controlled by the callee 62 * 63 * @param task 64 * @return 65 */ 66 struct thread_entry * 67 lua_thread_pool_get_for_task (struct rspamd_task *task); 68 69 /** 70 * The same, but used when task is not available 71 * 72 * @param cfg 73 * @return 74 */ 75 struct thread_entry * 76 lua_thread_pool_get_for_config (struct rspamd_config *cfg); 77 78 /** 79 * Return thread into the list of available ones. It can't be done with yielded or dead threads. 80 * 81 * @param pool 82 * @param thread_entry 83 */ 84 void 85 lua_thread_pool_return_full (struct lua_thread_pool *pool, 86 struct thread_entry *thread_entry, 87 const gchar *loc); 88 89 #define lua_thread_pool_return(pool, thread_entry) \ 90 lua_thread_pool_return_full (pool, thread_entry, G_STRLOC) 91 92 /** 93 * Currently running thread. Typically needed in yielding point - to fill-up continuation. 94 * 95 * @param pool 96 * @return 97 */ 98 struct thread_entry * 99 lua_thread_pool_get_running_entry_full (struct lua_thread_pool *pool, 100 const gchar *loc); 101 102 #define lua_thread_pool_get_running_entry(pool) \ 103 lua_thread_pool_get_running_entry_full (pool, G_STRLOC) 104 105 /** 106 * Updates currently running thread 107 * 108 * @param pool 109 * @param thread_entry 110 */ 111 void 112 lua_thread_pool_set_running_entry_full (struct lua_thread_pool *pool, 113 struct thread_entry *thread_entry, 114 const gchar *loc); 115 116 #define lua_thread_pool_set_running_entry(pool, thread_entry) \ 117 lua_thread_pool_set_running_entry_full (pool, thread_entry, G_STRLOC) 118 119 /** 120 * Prevents yielded thread to be used for callback execution. lua_thread_pool_restore_callback() should be called afterwards. 121 * 122 * @param pool 123 * @param cbs 124 */ 125 void 126 lua_thread_pool_prepare_callback_full (struct lua_thread_pool *pool, 127 struct lua_callback_state *cbs, const gchar *loc); 128 129 #define lua_thread_pool_prepare_callback(pool, cbs) \ 130 lua_thread_pool_prepare_callback_full (pool, cbs, G_STRLOC) 131 132 /** 133 * Restores state after lua_thread_pool_prepare_callback () usage 134 * 135 * @param cbs 136 */ 137 void 138 lua_thread_pool_restore_callback_full (struct lua_callback_state *cbs, 139 const gchar *loc); 140 141 #define lua_thread_pool_restore_callback(cbs) \ 142 lua_thread_pool_restore_callback_full (cbs, G_STRLOC) 143 144 /** 145 * Acts like lua_call but the tread is able to suspend execution. 146 * As soon as the call is over, call either thread_entry::finish_callback or thread_entry::error_callback. 147 * 148 * @param thread_entry 149 * @param narg 150 */ 151 void 152 lua_thread_call_full (struct thread_entry *thread_entry, 153 int narg, 154 const gchar *loc); 155 156 #define lua_thread_call(thread_entry, narg) \ 157 lua_thread_call_full (thread_entry, narg, G_STRLOC) 158 159 /** 160 * Yields thread. should be only called in return statement 161 * @param thread_entry 162 * @param nresults 163 * @return 164 */ 165 int 166 lua_thread_yield_full (struct thread_entry *thread_entry, int nresults, 167 const gchar *loc); 168 169 #define lua_thread_yield(thread_entry, narg) \ 170 lua_thread_yield_full (thread_entry, narg, G_STRLOC) 171 172 /** 173 * Resumes suspended by lua_yield_thread () thread 174 * @param task 175 * @param thread_entry 176 * @param narg 177 */ 178 void 179 lua_thread_resume_full (struct thread_entry *thread_entry, 180 int narg, 181 const gchar *loc); 182 183 #define lua_thread_resume(thread_entry, narg) \ 184 lua_thread_resume_full (thread_entry, narg, G_STRLOC) 185 186 /** 187 * Terminates thread pool entry and fill the pool with another thread entry if needed 188 * @param pool 189 * @param thread_entry 190 * @param loc 191 */ 192 void 193 lua_thread_pool_terminate_entry_full (struct lua_thread_pool *pool, 194 struct thread_entry *thread_entry, 195 const gchar *loc, bool enforce); 196 #define lua_thread_pool_terminate_entry(pool, thread_entry) \ 197 lua_thread_pool_terminate_entry_full (pool, thread_entry, G_STRLOC, false) 198 199 #ifdef __cplusplus 200 } 201 #endif 202 203 #endif /* LUA_THREAD_POOL_H_ */ 204 205