struct thread_entry *thread_entry = lua_thread_pool_get (task->cfg->lua_thread_pool);
cd->thread_entry = thread_entry;
+ g_assert(thread_entry->cd == NULL);
+ thread_entry->cd = cd;
+
lua_State *thread = thread_entry->lua_state;
cd->stack_level = lua_gettop (cd->L);
}
}
+gint
+lua_yield_thread (struct thread_entry *thread_entry, gint nresults)
+{
+ g_assert (thread_entry->cd != NULL);
+
+ return lua_yield (thread_entry->lua_state, nresults);
+}
+
+void
+lua_resume_thread (struct rspamd_task *task, struct thread_entry *thread_entry, gint narg)
+{
+ g_assert (thread_entry->cd != NULL);
+
+ gint ret;
+
+ lua_thread_pool_set_running_entry (task->cfg->lua_thread_pool, thread_entry);
+ ret = lua_resume (thread_entry->lua_state, narg);
+
+ if (ret != LUA_YIELD) {
+ lua_metric_symbol_callback_return (task, thread_entry->cd, ret);
+ }
+}
+
static void
lua_metric_symbol_callback_return (struct rspamd_task *task, gpointer ud, gint ret)
{
g_assert (lua_gettop (thread) == cd->stack_level); /* we properly cleaned up the stack */
- lua_thread_pool_return(task->cfg->lua_thread_pool, cd->thread_entry);
+ lua_thread_pool_return (task->cfg->lua_thread_pool, cd->thread_entry);
}
cd->thread_entry = NULL;
* limitations under the License.
*/
#include "lua_common.h"
+#include "lua_thread_pool.h"
#include "utlist.h"
struct lua_dns_cbdata {
lua_State *L;
+ struct thread_entry *thread;
+ struct rspamd_task *task;
struct rspamd_dns_resolver *resolver;
gint cbref;
const gchar *to_resolve;
struct rdns_reply_entry *elt;
rspamd_inet_addr_t *addr;
- lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->cbref);
- presolver = lua_newuserdata (cd->L, sizeof (gpointer));
- rspamd_lua_setclass (cd->L, "rspamd{resolver}", -1);
+ if (cd->cbref != -1) {
+ lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->cbref);
- *presolver = cd->resolver;
- lua_pushstring (cd->L, cd->to_resolve);
+ presolver = lua_newuserdata (cd->L, sizeof (gpointer));
+ rspamd_lua_setclass (cd->L, "rspamd{resolver}", -1);
+
+ *presolver = cd->resolver;
+ lua_pushstring (cd->L, cd->to_resolve);
+ }
/*
* XXX: rework to handle different request types
lua_pushstring (cd->L, rdns_strerror (reply->code));
}
- if (cd->user_str != NULL) {
- lua_pushstring (cd->L, cd->user_str);
- }
- else {
- lua_pushnil (cd->L);
+ if (cd->cbref != -1) {
+ if (cd->user_str != NULL) {
+ lua_pushstring (cd->L, cd->user_str);
+ }
+ else {
+ lua_pushnil (cd->L);
+ }
}
lua_pushboolean (cd->L, reply->authenticated);
- if (lua_pcall (cd->L, 6, 0, 0) != 0) {
- msg_info ("call to dns callback failed: %s", lua_tostring (cd->L, -1));
- lua_pop (cd->L, 1);
- }
+ if (cd->cbref != -1) {
+ /*
+ * 1 - resolver
+ * 2 - to_resolve
+ * 3 - entries | nil
+ * 4 - error | nil
+ * 5 - user_str
+ * 6 - reply->authenticated
+ */
+ if (lua_pcall (cd->L, 6, 0, 0) != 0) {
+ msg_info ("call to dns callback failed: %s", lua_tostring (cd->L, -1));
+ lua_pop (cd->L, 1);
+ }
- /* Unref function */
- luaL_unref (cd->L, LUA_REGISTRYINDEX, cd->cbref);
+ /* Unref function */
+ luaL_unref (cd->L, LUA_REGISTRYINDEX, cd->cbref);
+ } else {
+ /*
+ * 1 - entries
+ * 2 - error | nil
+ * 3 - reply->authenticated
+ */
+ lua_resume_thread (cd->task, cd->thread, 3);
+ }
if (cd->s) {
rspamd_session_watcher_pop (cd->s, cd->w);
/* Check arguments */
if (!rspamd_lua_parse_table_arguments (L, first, &err,
- "session=U{session};mempool=U{mempool};*name=S;*callback=F;"
+ "session=U{session};mempool=U{mempool};*name=S;callback=F;"
"option=S;task=U{task};forced=B",
&session, &pool, &to_resolve, &cbref, &user_str, &task, &forced)) {
session = task->s;
}
- if (pool != NULL && to_resolve != NULL && cbref != -1) {
+ if (pool != NULL && to_resolve != NULL) {
cbdata = rspamd_mempool_alloc0 (pool, sizeof (struct lua_dns_cbdata));
cbdata->L = L;
cbdata->resolver = resolver;
}
}
else {
+ cbdata->thread = lua_thread_pool_get_running_entry (task->cfg->lua_thread_pool);
+ cbdata->task = task;
+
if (forced) {
ret = make_dns_request_task_forced (task,
lua_dns_callback,
}
if (ret) {
- lua_pushboolean (L, TRUE);
cbdata->s = session;
cbdata->w = rspamd_session_get_watcher (session);
rspamd_session_watcher_push (session);
+ if (cbdata->cbref != -1) {
+ /* callback was set up */
+ lua_pushboolean (L, TRUE);
+ } else {
+ /* this is coroutine-based call */
+ return lua_yield_thread (cbdata->thread, 0);
+ }
}
else {
lua_pushnil (L);