aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua/lua_thread_pool.h
blob: bdf5586d6f2239246a083a02d67b0131ee85d329 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef LUA_THREAD_POOL_H_
#define LUA_THREAD_POOL_H_

#include <lua.h>

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 becames 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(struct lua_thread_pool *pool, struct thread_entry *thread_entry);

/**
 * Currently running thread. Typically needed in yielding point - to fill-up continuation.
 *
 * @param pool
 * @return
 */
struct thread_entry *
lua_thread_pool_get_running_entry (struct lua_thread_pool *pool);

/**
 * Updates currently running thread
 *
 * @param pool
 * @param thread_entry
 */
void
lua_thread_pool_set_running_entry (struct lua_thread_pool *pool, struct thread_entry *thread_entry);

/**
 * 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 (struct lua_thread_pool *pool, struct lua_callback_state *cbs);

/**
 * Restores state after lua_thread_pool_prepare_callback () usage
 *
 * @param cbs
 */
void
lua_thread_pool_restore_callback (struct lua_callback_state *cbs);


/**
 * 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 (struct thread_entry *thread_entry, int narg);

/**
 * Yields thread. should be only called in return statement
 * @param thread_entry
 * @param nresults
 * @return
 */
int
lua_thread_yield (struct thread_entry *thread_entry, int nresults);

/**
 * Resumes suspended by lua_yield_thread () thread
 * @param task
 * @param thread_entry
 * @param narg
 */
void
lua_thread_resume (struct thread_entry *thread_entry, int narg);

#endif /* LUA_THREAD_POOL_H_ */