Skip to content
Snippets Groups Projects
Commit 65128730 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Improve trigger API to accept context and allow a list of triggers.

parent 0d320f03
No related branches found
No related tags found
No related merge requests found
...@@ -84,9 +84,9 @@ session_exists(uint32_t sid) ...@@ -84,9 +84,9 @@ session_exists(uint32_t sid)
} }
/* The global on-connect trigger. */ /* The global on-connect trigger. */
extern struct trigger session_on_connect; extern struct rlist session_on_connect;
/* The global on-disconnect trigger. */ /* The global on-disconnect trigger. */
extern struct trigger session_on_disconnect; extern struct rlist session_on_disconnect;
void void
session_init(); session_init();
......
#ifndef INCLUDES_TARANTOOL_TRIGGER_H #ifndef INCLUDES_TARANTOOL_TRIGGER_H
#define INCLUDES_TARANTOOL_TRIGGER_H #define INCLUDES_TARANTOOL_TRIGGER_H
# /*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. 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 BY <COPYRIGHT HOLDER> ``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
* <COPYRIGHT HOLDER> OR CONTRIBUTORS 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 "rlist.h"
/** /**
* Type of the callback which may be invoked * Type of the callback which may be invoked
* on an event. * on an event.
*/ */
typedef void (*trigger_f)(void *); typedef void (*trigger_f)(struct trigger *trigger, void *event);
struct trigger struct trigger
{ {
trigger_f trigger; struct rlist link;
void *param; trigger_f run;
}; };
static inline void static inline void
trigger_run(struct trigger *trigger) trigger_run(struct rlist *list, void *event)
{
struct trigger *trigger;
rlist_foreach_entry(trigger, list, link)
trigger->run(trigger, event);
}
static inline void
trigger_set(struct rlist *list, struct trigger *trigger)
{ {
if (trigger->trigger) rlist_add_entry(list, trigger, link);
trigger->trigger(trigger->param);
} }
static inline void static inline void
trigger_set(struct trigger *trigger, trigger_f func, void *param) trigger_clear(struct trigger *trigger)
{ {
trigger->trigger = func; rlist_del_entry(trigger, link);
trigger->param = param;
} }
#endif /* INCLUDES_TARANTOOL_TRIGGER_H */ #endif /* INCLUDES_TARANTOOL_TRIGGER_H */
...@@ -92,20 +92,15 @@ lbox_session_peer(struct lua_State *L) ...@@ -92,20 +92,15 @@ lbox_session_peer(struct lua_State *L)
struct lbox_session_trigger struct lbox_session_trigger
{ {
struct trigger *trigger; struct trigger trigger;
int ref; int ref;
}; };
static struct lbox_session_trigger on_connect =
{ &session_on_connect, LUA_NOREF};
static struct lbox_session_trigger on_disconnect =
{ &session_on_disconnect, LUA_NOREF};
static void static void
lbox_session_run_trigger(void *param) lbox_session_run_trigger(struct trigger *trg, void * /* event */)
{ {
struct lbox_session_trigger *trigger = struct lbox_session_trigger *trigger =
(struct lbox_session_trigger *) param; (struct lbox_session_trigger *) trg;
/* Copy the referenced callable object object stack. */ /* Copy the referenced callable object object stack. */
lua_State *L = lua_newthread(tarantool_L); lua_State *L = lua_newthread(tarantool_L);
int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX);
...@@ -125,8 +120,14 @@ lbox_session_run_trigger(void *param) ...@@ -125,8 +120,14 @@ lbox_session_run_trigger(void *param)
} }
} }
static struct lbox_session_trigger on_connect =
{ { rlist_nil, lbox_session_run_trigger }, LUA_NOREF};
static struct lbox_session_trigger on_disconnect =
{ { rlist_nil, lbox_session_run_trigger }, LUA_NOREF};
static int static int
lbox_session_set_trigger(struct lua_State *L, lbox_session_set_trigger(struct lua_State *L,
struct rlist *list,
struct lbox_session_trigger *trigger) struct lbox_session_trigger *trigger)
{ {
if (lua_gettop(L) != 1 || if (lua_gettop(L) != 1 ||
...@@ -139,6 +140,7 @@ lbox_session_set_trigger(struct lua_State *L, ...@@ -139,6 +140,7 @@ lbox_session_set_trigger(struct lua_State *L,
if (trigger->ref != LUA_NOREF) { if (trigger->ref != LUA_NOREF) {
lua_rawgeti(L, LUA_REGISTRYINDEX, trigger->ref); lua_rawgeti(L, LUA_REGISTRYINDEX, trigger->ref);
luaL_unref(L, LUA_REGISTRYINDEX, trigger->ref); luaL_unref(L, LUA_REGISTRYINDEX, trigger->ref);
trigger_clear(&trigger->trigger);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
...@@ -149,13 +151,12 @@ lbox_session_set_trigger(struct lua_State *L, ...@@ -149,13 +151,12 @@ lbox_session_set_trigger(struct lua_State *L,
*/ */
if (lua_type(L, -2) == LUA_TNIL) { if (lua_type(L, -2) == LUA_TNIL) {
trigger->ref = LUA_NOREF; trigger->ref = LUA_NOREF;
trigger_set(trigger->trigger, NULL, NULL);
} else { } else {
/* Move the trigger to the top of the stack. */ /* Move the trigger to the top of the stack. */
lua_insert(L, -2); lua_insert(L, -2);
/* Reference the new trigger. Pops it. */ /* Reference the new trigger. Pops it. */
trigger->ref = luaL_ref(L, LUA_REGISTRYINDEX); trigger->ref = luaL_ref(L, LUA_REGISTRYINDEX);
trigger_set(trigger->trigger, lbox_session_run_trigger, trigger); trigger_set(list, &trigger->trigger);
} }
/* Return the old trigger. */ /* Return the old trigger. */
return 1; return 1;
...@@ -164,13 +165,14 @@ lbox_session_set_trigger(struct lua_State *L, ...@@ -164,13 +165,14 @@ lbox_session_set_trigger(struct lua_State *L,
static int static int
lbox_session_on_connect(struct lua_State *L) lbox_session_on_connect(struct lua_State *L)
{ {
return lbox_session_set_trigger(L, &on_connect); return lbox_session_set_trigger(L, &session_on_connect, &on_connect);
} }
static int static int
lbox_session_on_disconnect(struct lua_State *L) lbox_session_on_disconnect(struct lua_State *L)
{ {
return lbox_session_set_trigger(L, &on_disconnect); return lbox_session_set_trigger(L, &session_on_disconnect,
&on_disconnect);
} }
static const struct luaL_reg lbox_session_meta [] = { static const struct luaL_reg lbox_session_meta [] = {
......
...@@ -37,8 +37,8 @@ uint32_t sid_max; ...@@ -37,8 +37,8 @@ uint32_t sid_max;
static struct mh_i32ptr_t *session_registry; static struct mh_i32ptr_t *session_registry;
struct trigger session_on_connect; RLIST_HEAD(session_on_connect);
struct trigger session_on_disconnect; RLIST_HEAD(session_on_disconnect);
uint32_t uint32_t
session_create(int fd) session_create(int fd)
...@@ -64,7 +64,7 @@ session_create(int fd) ...@@ -64,7 +64,7 @@ session_create(int fd)
*/ */
fiber_set_sid(fiber, sid); fiber_set_sid(fiber, sid);
try { try {
trigger_run(&session_on_connect); trigger_run(&session_on_connect, NULL);
} catch (const Exception& e) { } catch (const Exception& e) {
fiber_set_sid(fiber, 0); fiber_set_sid(fiber, 0);
mh_i32ptr_remove(session_registry, &node, NULL); mh_i32ptr_remove(session_registry, &node, NULL);
...@@ -80,7 +80,7 @@ session_destroy(uint32_t sid) ...@@ -80,7 +80,7 @@ session_destroy(uint32_t sid)
return; return;
try { try {
trigger_run(&session_on_disconnect); trigger_run(&session_on_disconnect, NULL);
} catch (const Exception& e) { } catch (const Exception& e) {
e.log(); e.log();
} catch (...) { } catch (...) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment