]> source.dussan.org Git - rspamd.git/commitdiff
* Add async_session and memory pool objects lua bindings.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 9 Jul 2012 17:45:03 +0000 (21:45 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Mon, 9 Jul 2012 17:45:03 +0000 (21:45 +0400)
src/lua/CMakeLists.txt
src/lua/lua_common.c
src/lua/lua_common.h
src/lua/lua_config.c
src/lua/lua_mempool.c [new file with mode: 0644]
src/lua/lua_session.c [new file with mode: 0644]
src/lua/lua_task.c

index a2823ad7be12a3d59e725dd896be274b32427185..93958674bae56b6e14197c29e906789d4a503ec1 100644 (file)
@@ -10,7 +10,9 @@ SET(LUASRC                      lua_common.c
                                          lua_xmlrpc.c
                                          lua_http.c
                                          lua_redis.c
-                                         lua_upstream.c)
+                                         lua_upstream.c
+                                         lua_mempool.c
+                                         lua_session.c)
 
 ADD_LIBRARY(rspamd-lua ${LINK_TYPE} ${LUASRC})
 SET_TARGET_PROPERTIES(rspamd-lua PROPERTIES VERSION ${RSPAMD_VERSION})
index 4a62a7d0277c13475980a9b687c76c187498d4cd..62fb5389b664ba7f96f132e0b80962e1b3bb6257 100644 (file)
@@ -252,7 +252,9 @@ init_lua (struct config_file *cfg)
 
        (void)luaopen_rspamd (L);
        (void)luaopen_logger (L);
+       (void)luaopen_mempool (L);
        (void)luaopen_config (L);
+       (void)luaopen_session (L);
        (void)luaopen_radix (L);
        (void)luaopen_hash_table (L);
        (void)luaopen_trie (L);
index c138a35a2fcd0c0de7dc47e174fdc40da25ac62f..daab695fc32708fd8a032968c4a536c2169beaf4 100644 (file)
@@ -62,6 +62,9 @@ gint luaopen_xmlrpc (lua_State * L);
 gint luaopen_http (lua_State * L);
 gint luaopen_redis (lua_State * L);
 gint luaopen_upstream (lua_State * L);
+gint luaopen_mempool (lua_State * L);
+gint luaopen_session (lua_State * L);
+
 void init_lua (struct config_file *cfg);
 gboolean init_lua_filters (struct config_file *cfg);
 
@@ -88,6 +91,8 @@ gboolean lua_handle_param (struct worker_task *task, gchar *mname, gchar *optnam
 gboolean lua_check_condition (struct config_file *cfg, const gchar *condition);
 void lua_dumpstack (lua_State *L);
 
+struct memory_pool_s *lua_check_mempool (lua_State * L);
+
 
 #endif /* WITH_LUA */
 #endif /* RSPAMD_LUA_H */
index 0e63f6421b8edf386f07e386db1cb84abd544c2e..2258c03aa06bdf399bf43086c3b52493f4ad1f5d 100644 (file)
@@ -35,6 +35,7 @@
 /* Config file methods */
 LUA_FUNCTION_DEF (config, get_module_opt);
 LUA_FUNCTION_DEF (config, get_all_opt);
+LUA_FUNCTION_DEF (config, get_mempool);
 LUA_FUNCTION_DEF (config, register_function);
 LUA_FUNCTION_DEF (config, add_radix_map);
 LUA_FUNCTION_DEF (config, add_hash_map);
@@ -51,6 +52,7 @@ LUA_FUNCTION_DEF (config, get_api_version);
 
 static const struct luaL_reg    configlib_m[] = {
        LUA_INTERFACE_DEF (config, get_module_opt),
+       LUA_INTERFACE_DEF (config, get_mempool),
        LUA_INTERFACE_DEF (config, get_all_opt),
        LUA_INTERFACE_DEF (config, register_function),
        LUA_INTERFACE_DEF (config, add_radix_map),
@@ -169,6 +171,20 @@ lua_config_get_module_opt (lua_State * L)
        return 1;
 }
 
+static int
+lua_config_get_mempool (lua_State * L)
+{
+       memory_pool_t                  **ppool;
+       struct config_file             *cfg = lua_check_config (L);
+
+       if (cfg != NULL) {
+               ppool = lua_newuserdata (L, sizeof (memory_pool_t *));
+               lua_setclass (L, "rspamd{mempool}", -1);
+               *ppool = cfg->cfg_pool;
+       }
+       return 1;
+}
+
 static gint
 opt_compare (gconstpointer a, gconstpointer b)
 {
diff --git a/src/lua/lua_mempool.c b/src/lua/lua_mempool.c
new file mode 100644 (file)
index 0000000..44fb3fe
--- /dev/null
@@ -0,0 +1,243 @@
+/* Copyright (c) 2010-2012, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "lua_common.h"
+#include "mem_pool.h"
+
+/* Public prototypes */
+struct memory_pool_s *lua_check_mempool (lua_State * L);
+gint luaopen_mempool (lua_State * L);
+
+/* Lua bindings */
+LUA_FUNCTION_DEF (mempool, create);
+LUA_FUNCTION_DEF (mempool, memory_pool_add_destructor);
+LUA_FUNCTION_DEF (mempool, memory_pool_delete);
+LUA_FUNCTION_DEF (mempool, memory_pool_stat);
+LUA_FUNCTION_DEF (mempool, memory_pool_get_size);
+LUA_FUNCTION_DEF (mempool, memory_pool_set_variable);
+LUA_FUNCTION_DEF (mempool, memory_pool_get_variable);
+
+static const struct luaL_reg    mempoollib_m[] = {
+       LUA_INTERFACE_DEF (mempool, memory_pool_add_destructor),
+       LUA_INTERFACE_DEF (mempool, memory_pool_stat),
+       LUA_INTERFACE_DEF (mempool, memory_pool_get_size),
+       LUA_INTERFACE_DEF (mempool, memory_pool_set_variable),
+       LUA_INTERFACE_DEF (mempool, memory_pool_get_variable),
+       {"__gc", lua_mempool_memory_pool_delete},
+       {"__tostring", lua_class_tostring},
+       {NULL, NULL}
+};
+
+static const struct luaL_reg    mempoollib_f[] = {
+       LUA_INTERFACE_DEF (mempool, create),
+       {NULL, NULL}
+};
+
+/*
+ * Struct for lua destructor
+ */
+
+struct lua_mempool_udata {
+       lua_State *L;
+       gint cbref;
+       memory_pool_t *mempool;
+};
+
+struct memory_pool_s      *
+lua_check_mempool (lua_State * L)
+{
+       void                                                            *ud = luaL_checkudata (L, 1, "rspamd{mempool}");
+       luaL_argcheck (L, ud != NULL, 1, "'mempool' expected");
+       return ud ? *((struct memory_pool_s **)ud) : NULL;
+}
+
+
+static int
+lua_mempool_create (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = memory_pool_new (memory_pool_get_size ()), **pmempool;
+
+       if (mempool) {
+               pmempool = lua_newuserdata (L, sizeof (struct memory_pool_s *));
+               lua_setclass (L, "rspamd{mempool}", -1);
+               *pmempool = mempool;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static void
+lua_mempool_destructor_func (gpointer p)
+{
+       struct lua_mempool_udata                                *ud = p;
+       gboolean                                                                 need_unlock = FALSE;
+
+       /* Avoid LOR here as mutex can be acquired before in lua_call */
+       if (g_mutex_trylock (lua_mtx)) {
+               need_unlock = TRUE;
+       }
+       lua_rawgeti (ud->L, LUA_REGISTRYINDEX, ud->cbref);
+       if (lua_pcall (ud->L, 0, 0, 0) != 0) {
+               msg_info ("call to destructor failed: %s", lua_tostring (ud->L, -1));
+       }
+       luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
+       if (need_unlock) {
+               g_mutex_unlock (lua_mtx);
+       }
+}
+
+static int
+lua_mempool_memory_pool_add_destructor (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+       struct lua_mempool_udata                                *ud;
+
+       if (mempool) {
+               if (lua_isfunction (L, 2)) {
+                       ud = memory_pool_alloc (mempool, sizeof (struct lua_mempool_udata));
+                       lua_pushvalue (L, 2);
+                       /* Get a reference */
+                       ud->cbref = luaL_ref (L, LUA_REGISTRYINDEX);
+                       ud->L = L;
+                       ud->mempool = mempool;
+                       memory_pool_add_destructor (mempool, lua_mempool_destructor_func, ud);
+               }
+               else {
+                       msg_err ("trying to add destructor without function");
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_mempool_memory_pool_delete (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+
+       if (mempool) {
+               memory_pool_delete (mempool);
+               return 0;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_mempool_memory_pool_stat (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+
+       if (mempool) {
+               
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_mempool_memory_pool_get_size (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+
+       if (mempool) {
+               lua_pushinteger (L, memory_pool_get_size ());
+               return 0;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_mempool_memory_pool_set_variable (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+       const gchar                                                             *var = luaL_checkstring (L, 2),
+                                                                                       *value = luaL_checkstring (L, 3);
+
+       if (mempool && var && value) {
+               memory_pool_set_variable (mempool, var, memory_pool_strdup (mempool, value), NULL);
+               return 0;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_mempool_memory_pool_get_variable (lua_State *L)
+{
+       struct memory_pool_s                                    *mempool = lua_check_mempool (L);
+       const gchar                                                             *var = luaL_checkstring (L, 2);
+       gchar                                                                   *value;
+
+       if (mempool && var) {
+               value = memory_pool_get_variable (mempool, var);
+               if (value) {
+                       lua_pushstring (L, value);
+               }
+               else {
+                       lua_pushnil (L);
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+gint
+luaopen_mempool (lua_State * L)
+{
+       luaL_newmetatable (L, "rspamd{mempool}");
+       lua_pushstring (L, "__index");
+       lua_pushvalue (L, -2);
+       lua_settable (L, -3);
+
+       lua_pushstring (L, "class");
+       lua_pushstring (L, "rspamd{mempool}");
+       lua_rawset (L, -3);
+
+       luaL_openlib (L, NULL, mempoollib_m, 0);
+       luaL_openlib(L, "rspamd_mempool", mempoollib_f, 0);
+
+       return 1;       
+}
diff --git a/src/lua/lua_session.c b/src/lua/lua_session.c
new file mode 100644 (file)
index 0000000..37a4196
--- /dev/null
@@ -0,0 +1,340 @@
+/* Copyright (c) 2010-2012, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "lua_common.h"
+
+/* Public prototypes */
+struct rspamd_async_session *lua_check_session (lua_State * L);
+gint luaopen_session (lua_State * L);
+
+/* Lua bindings */
+LUA_FUNCTION_DEF (session, register_async_event);
+LUA_FUNCTION_DEF (session, remove_normal_event);
+LUA_FUNCTION_DEF (session, check_session_pending);
+LUA_FUNCTION_DEF (session, create);
+LUA_FUNCTION_DEF (session, delete);
+
+static const struct luaL_reg    sessionlib_m[] = {
+       LUA_INTERFACE_DEF (session, register_async_event),
+       LUA_INTERFACE_DEF (session, remove_normal_event),
+       LUA_INTERFACE_DEF (session, check_session_pending),
+       {"__gc", lua_session_delete},
+       {"__tostring", lua_class_tostring},
+       {NULL, NULL}
+};
+
+static const struct luaL_reg    sessionlib_f[] = {
+       LUA_INTERFACE_DEF (session, create),
+       {NULL, NULL}
+};
+
+static const struct luaL_reg    eventlib_m[] = {
+       {"__tostring", lua_class_tostring},
+       {NULL, NULL}
+};
+
+struct lua_session_udata {
+       lua_State *L;
+       gint cbref_fin;
+       gint cbref_restore;
+       gint cbref_cleanup;
+       struct rspamd_async_session *session;
+};
+
+struct lua_event_udata {
+       lua_State *L;
+       gint cbref;
+       struct rspamd_async_session *session;
+};
+
+struct rspamd_async_session      *
+lua_check_session (lua_State * L)
+{
+       void                                                            *ud = luaL_checkudata (L, 1, "rspamd{session}");
+       luaL_argcheck (L, ud != NULL, 1, "'session' expected");
+       return ud ? *((struct rspamd_async_session **)ud) : NULL;
+}
+
+struct rspamd_async_event      *
+lua_check_event (lua_State * L, gint pos)
+{
+       void                                                            *ud = luaL_checkudata (L, pos, "rspamd{event}");
+       luaL_argcheck (L, ud != NULL, 1, "'event' expected");
+       return ud ? *((struct rspamd_async_event **)ud) : NULL;
+}
+
+/* Usage: rspamd_session.create(pool, finalizer, restore, cleanup) */
+
+static gboolean
+lua_session_finalizer (gpointer ud)
+{
+       struct lua_session_udata                                        *cbdata = ud;
+       gboolean                                                                        need_unlock = FALSE;
+
+       /* Avoid LOR here as mutex can be acquired before in lua_call */
+       if (g_mutex_trylock (lua_mtx)) {
+               need_unlock = TRUE;
+       }
+
+       /* Call finalizer function */
+       lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_fin);
+       if (lua_pcall (cbdata->L, 0, 0, 0) != 0) {
+               msg_info ("call to session finalizer failed: %s", lua_tostring (cbdata->L, -1));
+       }
+       luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_fin);
+       if (need_unlock) {
+               g_mutex_unlock (lua_mtx);
+       }
+
+       return TRUE;
+}
+
+static void
+lua_session_restore (gpointer ud)
+{
+       struct lua_session_udata                                        *cbdata = ud;
+       gboolean                                                                         need_unlock = FALSE;
+
+       if (cbdata->cbref_restore) {
+       /* Avoid LOR here as mutex can be acquired before in lua_call */
+               if (g_mutex_trylock (lua_mtx)) {
+                       need_unlock = TRUE;
+               }
+
+               /* Call restorer function */
+               lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_restore);
+               if (lua_pcall (cbdata->L, 0, 0, 0) != 0) {
+                       msg_info ("call to session restorer failed: %s", lua_tostring (cbdata->L, -1));
+               }
+               luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_restore);
+               if (need_unlock) {
+                       g_mutex_unlock (lua_mtx);
+               }
+       }
+}
+
+static void
+lua_session_cleanup (gpointer ud)
+{
+       struct lua_session_udata                                        *cbdata = ud;
+       gboolean                                                                         need_unlock = FALSE;
+
+       if (cbdata->cbref_cleanup) {
+       /* Avoid LOR here as mutex can be acquired before in lua_call */
+               if (g_mutex_trylock (lua_mtx)) {
+                       need_unlock = TRUE;
+               }
+
+               /* Call restorer function */
+               lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_cleanup);
+               if (lua_pcall (cbdata->L, 0, 0, 0) != 0) {
+                       msg_info ("call to session cleanup failed: %s", lua_tostring (cbdata->L, -1));
+               }
+               luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref_cleanup);
+               if (need_unlock) {
+                       g_mutex_unlock (lua_mtx);
+               }
+       }
+}
+
+static int
+lua_session_create (lua_State *L)
+{
+       struct rspamd_async_session                                     *session, **psession;
+       struct lua_session_udata                                        *cbdata;
+       memory_pool_t                                                           *mempool;
+
+
+
+       if (lua_gettop (L) < 2 || lua_gettop (L) > 4) {
+               msg_err ("invalid arguments number to rspamd_session.create");
+               lua_pushnil (L);
+               return 1;
+       }
+
+       mempool = lua_check_mempool (L);
+       if (mempool == NULL) {
+               msg_err ("invalid mempool argument to rspamd_session.create");
+               lua_pushnil (L);
+               return 1;
+       }
+
+       if (!lua_isfunction (L, 2)) {
+               msg_err ("invalid finalizer argument to rspamd_session.create");
+               lua_pushnil (L);
+               return 1;
+       }
+
+       cbdata = memory_pool_alloc0 (mempool, sizeof (struct lua_session_udata));
+       cbdata->L = L;
+       lua_pushvalue (L, 2);
+       cbdata->cbref_fin = luaL_ref (L, LUA_REGISTRYINDEX);
+
+       if (lua_gettop (L) > 2) {
+               /* Also add restore callback */
+               if (lua_isfunction (L, 3)) {
+                       lua_pushvalue (L, 3);
+                       cbdata->cbref_restore = luaL_ref (L, LUA_REGISTRYINDEX);
+               }
+       }
+
+       if (lua_gettop (L) > 3) {
+               /* Also add cleanup callback */
+               if (lua_isfunction (L, 4)) {
+                       lua_pushvalue (L, 4);
+                       cbdata->cbref_cleanup = luaL_ref (L, LUA_REGISTRYINDEX);
+               }
+       }
+       session = new_async_session (mempool, lua_session_finalizer, lua_session_restore, lua_session_cleanup, cbdata);
+       cbdata->session = session;
+       psession = lua_newuserdata (L, sizeof (struct real_name *));
+       lua_setclass (L, "rspamd{session}", -1);
+       *psession = session;
+
+       return 1;
+}
+
+static int
+lua_session_delete (lua_State *L)
+{
+       struct rspamd_async_session                                     *session = lua_check_session (L);
+
+       if (session) {
+               destroy_session (session);
+               return 0;
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static void
+lua_event_fin (gpointer ud)
+{
+       struct lua_event_udata                                          *cbdata = ud;
+       gboolean                                                                         need_unlock = FALSE;
+
+       if (cbdata->cbref) {
+       /* Avoid LOR here as mutex can be acquired before in lua_call */
+               if (g_mutex_trylock (lua_mtx)) {
+                       need_unlock = TRUE;
+               }
+
+               /* Call restorer function */
+               lua_rawgeti (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref);
+               if (lua_pcall (cbdata->L, 0, 0, 0) != 0) {
+                       msg_info ("call to event finalizer failed: %s", lua_tostring (cbdata->L, -1));
+               }
+               luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->cbref);
+               if (need_unlock) {
+                       g_mutex_unlock (lua_mtx);
+               }
+       }
+}
+
+static int
+lua_session_register_async_event (lua_State *L)
+{
+       struct rspamd_async_session                                     *session = lua_check_session (L);
+       struct lua_event_udata                                          *cbdata;
+       gpointer                                                                        *pdata;
+
+       if (session) {
+               if (lua_isfunction (L, 1)) {
+                       cbdata = memory_pool_alloc (session->pool, sizeof (struct lua_event_udata));
+                       cbdata->L = L;
+                       lua_pushvalue (L, 1);
+                       cbdata->cbref = luaL_ref (L, LUA_REGISTRYINDEX);
+                       cbdata->session = session;
+                       register_async_event (session, lua_event_fin, cbdata, g_quark_from_static_string ("lua event"));
+                       pdata = lua_newuserdata (L, sizeof (gpointer));
+                       lua_setclass (L, "rspamd{event}", -1);
+                       *pdata = cbdata;
+               }
+               else {
+                       msg_err ("invalid finalizer argument to register async event");
+               }
+       }
+       lua_pushnil (L);
+
+       return 1;
+}
+
+static int
+lua_session_remove_normal_event (lua_State *L)
+{
+       struct rspamd_async_session                                     *session = lua_check_session (L);
+       gpointer                                                                         data;
+
+       if (session) {
+               data = lua_check_event (L, 2);
+               if (data) {
+                       remove_normal_event (session, lua_event_fin, data);
+                       return 0;
+               }
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+static int
+lua_session_check_session_pending (lua_State *L)
+{
+       struct rspamd_async_session                                     *session = lua_check_session (L);
+
+       if (session) {
+               
+       }
+       else {
+               lua_pushnil (L);
+       }
+
+       return 1;
+}
+
+gint
+luaopen_session (lua_State * L)
+{
+       luaL_newmetatable (L, "rspamd{session}");
+       lua_pushstring (L, "__index");
+       lua_pushvalue (L, -2);
+       lua_settable (L, -3);
+
+       lua_pushstring (L, "class");
+       lua_pushstring (L, "rspamd{session}");
+       lua_rawset (L, -3);
+
+       luaL_openlib (L, NULL, sessionlib_m, 0);
+       luaL_openlib(L, "rspamd_session", sessionlib_f, 0);
+
+       /* Simple event class */
+       lua_newclass (L, "rspamd{event}", eventlib_m);
+       luaL_openlib (L, "rspamd_event", null_reg, 0);
+
+       return 1;       
+}
index e44b873c0250ae9f40e83613f79cf766236c5246..3ef88e3906e156e57d60f671b50483a35e606ace 100644 (file)
@@ -44,6 +44,7 @@ extern stat_file_t* get_statfile_by_symbol (statfile_pool_t *pool, struct classi
 
 /* Task methods */
 LUA_FUNCTION_DEF (task, get_message);
+LUA_FUNCTION_DEF (task, get_mempool);
 LUA_FUNCTION_DEF (task, insert_result);
 LUA_FUNCTION_DEF (task, set_pre_result);
 LUA_FUNCTION_DEF (task, get_urls);
@@ -77,6 +78,7 @@ LUA_FUNCTION_DEF (task, learn_statfile);
 
 static const struct luaL_reg    tasklib_m[] = {
        LUA_INTERFACE_DEF (task, get_message),
+       LUA_INTERFACE_DEF (task, get_mempool),
        LUA_INTERFACE_DEF (task, insert_result),
        LUA_INTERFACE_DEF (task, set_pre_result),
        LUA_INTERFACE_DEF (task, get_urls),
@@ -207,7 +209,6 @@ lua_task_get_message (lua_State * L)
        struct worker_task             *task = lua_check_task (L);
 
        if (task != NULL) {
-               /* XXX write handler for message object */
                pmsg = lua_newuserdata (L, sizeof (GMimeMessage *));
                lua_setclass (L, "rspamd{message}", -1);
                *pmsg = task->message;
@@ -215,6 +216,20 @@ lua_task_get_message (lua_State * L)
        return 1;
 }
 
+static int
+lua_task_get_mempool (lua_State * L)
+{
+       memory_pool_t                  **ppool;
+       struct worker_task             *task = lua_check_task (L);
+
+       if (task != NULL) {
+               ppool = lua_newuserdata (L, sizeof (memory_pool_t *));
+               lua_setclass (L, "rspamd{mempool}", -1);
+               *ppool = task->task_pool;
+       }
+       return 1;
+}
+
 static gint
 lua_task_insert_result (lua_State * L)
 {