From: Thierry FOURNIER Date: Wed, 12 Jul 2017 12:31:10 +0000 (+0200) Subject: MINOR: tasks: Move Lua notification from Lua to tasks X-Git-Tag: v1.8-dev3~107 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d697596c6c7633130253d39064cc10e1e9bfb69b;p=thirdparty%2Fhaproxy.git MINOR: tasks: Move Lua notification from Lua to tasks These notification management function and structs are generic and it will be better to move in common parts. The notification management functions and structs have names containing some "lua" references because it was written for the Lua. This patch removes also these references. --- diff --git a/include/proto/task.h b/include/proto/task.h index 82e6f5322b..c6177d08e1 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -85,6 +85,7 @@ extern unsigned int tasks_run_queue_cur; extern unsigned int nb_tasks_cur; extern unsigned int niced_tasks; /* number of niced tasks in the run queue */ extern struct pool_head *pool2_task; +extern struct pool_head *pool2_notification; /* return 0 if task is in run queue, otherwise non-zero */ static inline int task_in_rq(struct task *t) @@ -254,6 +255,57 @@ static inline void task_schedule(struct task *task, int when) __task_queue(task); } +/* This function register a new signal. "lua" is the current lua + * execution context. It contains a pointer to the associated task. + * "link" is a list head attached to an other task that must be wake + * the lua task if an event occurs. This is useful with external + * events like TCP I/O or sleep functions. This funcion allocate + * memory for the signal. + */ +static inline struct notification *notification_new(struct list *purge, struct list *event, struct task *wakeup) +{ + struct notification *com = pool_alloc2(pool2_notification); + if (!com) + return NULL; + LIST_ADDQ(purge, &com->purge_me); + LIST_ADDQ(event, &com->wake_me); + com->task = wakeup; + return com; +} + +/* This function purge all the pending signals when the LUA execution + * is finished. This prevent than a coprocess try to wake a deleted + * task. This function remove the memory associated to the signal. + */ +static inline void notification_purge(struct list *purge) +{ + struct notification *com, *back; + + /* Delete all pending communication signals. */ + list_for_each_entry_safe(com, back, purge, purge_me) { + LIST_DEL(&com->purge_me); + LIST_DEL(&com->wake_me); + pool_free2(pool2_notification, com); + } +} + +/* This function sends signals. It wakes all the tasks attached + * to a list head, and remove the signal, and free the used + * memory. + */ +static inline void notification_wake(struct list *wake) +{ + struct notification *com, *back; + + /* Wake task and delete all pending communication signals. */ + list_for_each_entry_safe(com, back, wake, wake_me) { + LIST_DEL(&com->purge_me); + LIST_DEL(&com->wake_me); + task_wakeup(com->task, TASK_WOKEN_MSG); + pool_free2(pool2_notification, com); + } +} + /* * This does 3 things : * - wake up all expired tasks diff --git a/include/types/hlua.h b/include/types/hlua.h index a0a1e26561..c7405a3562 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -86,14 +86,6 @@ struct hlua { struct hlua_consistency cons; /* Store data consistency check. */ }; -struct hlua_com { - struct list purge_me; /* Part of the list of signals to be purged in the - case of the LUA execution stack crash. */ - struct list wake_me; /* Part of list of signals to be targeted if an - event occurs. */ - struct task *task; /* The task to be wake if an event occurs. */ -}; - /* This is a part of the list containing references to functions * called at the initialisation time. */ diff --git a/include/types/task.h b/include/types/task.h index 6dfae98acd..e0ae3823e7 100644 --- a/include/types/task.h +++ b/include/types/task.h @@ -50,6 +50,14 @@ */ #define TASK_REASON_SHIFT 8 +struct notification { + struct list purge_me; /* Part of the list of signals to be purged in the + case of the LUA execution stack crash. */ + struct list wake_me; /* Part of list of signals to be targeted if an + event occurs. */ + struct task *task; /* The task to be wake if an event occurs. */ +}; + /* The base for all tasks */ struct task { struct eb32_node rq; /* ebtree node used to hold the task in the run queue */ diff --git a/src/hlua.c b/src/hlua.c index 98fed3bc36..acf5896968 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -141,11 +141,6 @@ struct hlua gL; */ struct pool_head *pool2_hlua; -/* This is the memory pool containing all the signal structs. These - * struct are used to store each requiered signal between two tasks. - */ -struct pool_head *pool2_hlua_com; - /* Used for Socket connection. */ static struct proxy socket_proxy; static struct server socket_tcp; @@ -295,57 +290,6 @@ static int hlua_pusherror(lua_State *L, const char *fmt, ...) return 1; } -/* This function register a new signal. "lua" is the current lua - * execution context. It contains a pointer to the associated task. - * "link" is a list head attached to an other task that must be wake - * the lua task if an event occurs. This is useful with external - * events like TCP I/O or sleep functions. This funcion allocate - * memory for the signal. - */ -static struct hlua_com *hlua_com_new(struct list *purge, struct list *event, struct task *wakeup) -{ - struct hlua_com *com = pool_alloc2(pool2_hlua_com); - if (!com) - return NULL; - LIST_ADDQ(purge, &com->purge_me); - LIST_ADDQ(event, &com->wake_me); - com->task = wakeup; - return com; -} - -/* This function purge all the pending signals when the LUA execution - * is finished. This prevent than a coprocess try to wake a deleted - * task. This function remove the memory associated to the signal. - */ -static void hlua_com_purge(struct list *purge) -{ - struct hlua_com *com, *back; - - /* Delete all pending communication signals. */ - list_for_each_entry_safe(com, back, purge, purge_me) { - LIST_DEL(&com->purge_me); - LIST_DEL(&com->wake_me); - pool_free2(pool2_hlua_com, com); - } -} - -/* This function sends signals. It wakes all the tasks attached - * to a list head, and remove the signal, and free the used - * memory. - */ -static void hlua_com_wake(struct list *wake) -{ - struct hlua_com *com, *back; - - /* Wake task and delete all pending communication signals. */ - list_for_each_entry_safe(com, back, wake, wake_me) { - LIST_DEL(&com->purge_me); - LIST_DEL(&com->wake_me); - task_wakeup(com->task, TASK_WOKEN_MSG); - pool_free2(pool2_hlua_com, com); - } -} - /* This functions is used with sample fetch and converters. It * converts the HAProxy configuration argument in a lua stack * values. @@ -881,7 +825,7 @@ void hlua_ctx_destroy(struct hlua *lua) goto end; /* Purge all the pending signals. */ - hlua_com_purge(&lua->com); + notification_purge(&lua->com); if (!SET_SAFE_LJMP(lua->T)) return; @@ -1164,20 +1108,20 @@ resume_execution: break; case HLUA_E_ERRMSG: - hlua_com_purge(&lua->com); + notification_purge(&lua->com); hlua_ctx_renew(lua, 1); HLUA_CLR_RUN(lua); break; case HLUA_E_ERR: HLUA_CLR_RUN(lua); - hlua_com_purge(&lua->com); + notification_purge(&lua->com); hlua_ctx_renew(lua, 0); break; case HLUA_E_OK: HLUA_CLR_RUN(lua); - hlua_com_purge(&lua->com); + notification_purge(&lua->com); break; } @@ -1552,8 +1496,8 @@ static void hlua_socket_handler(struct appctx *appctx) si_shutw(si); si_shutr(si); si_ic(si)->flags |= CF_READ_NULL; - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_read); - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); stream_shutdown(si_strm(si), SF_ERR_KILLED); } @@ -1564,18 +1508,18 @@ static void hlua_socket_handler(struct appctx *appctx) si_shutw(si); si_shutr(si); si_ic(si)->flags |= CF_READ_NULL; - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_read); - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); return; } /* If we cant write, wakeup the pending write signals. */ if (channel_output_closed(si_ic(si))) - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); /* If we cant read, wakeup the pending read signals. */ if (channel_input_closed(si_oc(si))) - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); /* if the connection is not estabkished, inform the stream that we want * to be notified whenever the connection completes. @@ -1591,11 +1535,11 @@ static void hlua_socket_handler(struct appctx *appctx) /* Wake the tasks which wants to write if the buffer have avalaible space. */ if (channel_may_recv(si_ic(si))) - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); /* Wake the tasks which wants to read if the buffer contains data. */ if (!channel_is_empty(si_oc(si))) - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); } /* This function is called when the "struct stream" is destroyed. @@ -1608,8 +1552,8 @@ static void hlua_socket_release(struct appctx *appctx) xref_disconnect(&appctx->ctx.hlua_cosocket.xref); /* Wake all the task waiting for me. */ - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_read); - hlua_com_wake(&appctx->ctx.hlua_cosocket.wake_on_write); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read); + notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write); } /* If the garbage collectio of the object is launch, nobody @@ -1812,7 +1756,7 @@ connection_closed: connection_empty: appctx = objt_appctx(s->si[0].end); - if (!hlua_com_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_read, hlua->task)) + if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_read, hlua->task)) WILL_LJMP(luaL_error(L, "out of memory")); WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0)); return 0; @@ -1952,7 +1896,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext len = buffer_total_space(s->req.buf); if (len <= 0) { appctx = objt_appctx(s->si[0].end); - if (!hlua_com_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) + if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) WILL_LJMP(luaL_error(L, "out of memory")); goto hlua_socket_write_yield_return; } @@ -2246,7 +2190,7 @@ __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua return 1; } - if (!hlua_com_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) + if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) WILL_LJMP(luaL_error(L, "out of memory error")); WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0)); return 0; @@ -2328,7 +2272,7 @@ __LJMP static int hlua_socket_connect(struct lua_State *L) hlua->flags |= HLUA_MUST_GC; - if (!hlua_com_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) + if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) WILL_LJMP(luaL_error(L, "out of memory")); WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0)); @@ -7303,7 +7247,6 @@ void hlua_init(void) /* Initialise struct hlua and com signals pool */ pool2_hlua = create_pool("hlua", sizeof(struct hlua), MEM_F_SHARED); - pool2_hlua_com = create_pool("hlua_com", sizeof(struct hlua_com), MEM_F_SHARED); /* Register configuration keywords. */ cfg_register_keywords(&cfg_kws); diff --git a/src/task.c b/src/task.c index 63b46c87e5..8d4ab39e57 100644 --- a/src/task.c +++ b/src/task.c @@ -25,6 +25,11 @@ struct pool_head *pool2_task; +/* This is the memory pool containing all the signal structs. These + * struct are used to store each requiered signal between two tasks. + */ +struct pool_head *pool2_notification; + unsigned int nb_tasks = 0; unsigned int tasks_run_queue = 0; unsigned int tasks_run_queue_cur = 0; /* copy of the run queue size */ @@ -266,7 +271,12 @@ int init_task() memset(&timers, 0, sizeof(timers)); memset(&rqueue, 0, sizeof(rqueue)); pool2_task = create_pool("task", sizeof(struct task), MEM_F_SHARED); - return pool2_task != NULL; + if (!pool2_task) + return 0; + pool2_notification = create_pool("notification", sizeof(struct notification), MEM_F_SHARED); + if (!pool2_notification) + return 0; + return 1; } /*