From 2efa8629448aa0d202d85fd29ff5df5462dee4f0 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 22 Nov 2016 11:03:05 +0200 Subject: [PATCH] Remove listmanager code The code prevented scaling by imposing global spinlocks for the DCBs and SESSIONs. Removing this list means that a thread-local list must be taken into use to replace it. --- include/maxscale/dcb.h | 3 - include/maxscale/session.h | 4 - server/core/CMakeLists.txt | 2 +- server/core/config.c | 4 - server/core/dcb.c | 133 ++++----- server/core/gateway.cc | 5 - server/core/session.c | 324 +++++++-------------- server/modules/filter/tee/tee.c | 4 +- server/modules/routing/debugcli/debugcmd.c | 121 ++++---- 9 files changed, 222 insertions(+), 378 deletions(-) diff --git a/include/maxscale/dcb.h b/include/maxscale/dcb.h index 42836bddc..ab12153b5 100644 --- a/include/maxscale/dcb.h +++ b/include/maxscale/dcb.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -216,7 +215,6 @@ typedef enum */ typedef struct dcb { - LIST_ENTRY_FIELDS skygw_chk_t dcb_chk_top; bool dcb_errhandle_called; /*< this can be called only once */ bool dcb_is_zombie; /**< Whether the DCB is in the zombie list */ @@ -326,7 +324,6 @@ void dcb_global_init(); int dcb_write(DCB *, GWBUF *); DCB *dcb_accept(DCB *listener, GWPROTOCOL *protocol_funcs); -bool dcb_pre_alloc(int number); DCB *dcb_alloc(dcb_role_t, struct servlistener *); void dcb_free(DCB *); void dcb_free_all_memory(DCB *dcb); diff --git a/include/maxscale/session.h b/include/maxscale/session.h index 66e15fed7..9dda114cf 100644 --- a/include/maxscale/session.h +++ b/include/maxscale/session.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -160,7 +159,6 @@ typedef enum */ typedef struct session { - LIST_ENTRY_FIELDS skygw_chk_t ses_chk_top; SPINLOCK ses_lock; session_state_t state; /*< Current descriptor state */ @@ -205,7 +203,6 @@ typedef struct session (sess)->tail.session, (buf)) SESSION *session_alloc(struct service *, struct dcb *); -bool session_pre_alloc(int number); SESSION *session_set_dummy(struct dcb *); bool session_free(SESSION *); int session_isvalid(SESSION *); @@ -220,7 +217,6 @@ void dprintSession(struct dcb *, SESSION *); void dListSessions(struct dcb *); char *session_state(session_state_t); bool session_link_dcb(SESSION *, struct dcb *); -SESSION* get_session_by_router_ses(void* rses); void session_enable_log_priority(SESSION* ses, int priority); void session_disable_log_priority(SESSION* ses, int priority); RESULTSET *sessionGetList(SESSIONLISTFILTER); diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 847d2fa42..9414df47e 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c ) +add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c ) target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl pthread crypt dl crypto inih z rt m stdc++) diff --git a/server/core/config.c b/server/core/config.c index 3c60038ae..51e1a82ec 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -702,10 +702,6 @@ config_load(const char *filename) { ss_dassert(!config_file); - /* Temporary - should use configuration values and test return value (bool) */ - dcb_pre_alloc(1000); - session_pre_alloc(250); - global_defaults(); feedback_defaults(); diff --git a/server/core/dcb.c b/server/core/dcb.c index c4f4446ef..83bc874e7 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -70,7 +70,6 @@ #include #include #include -#include #include #include #include @@ -94,10 +93,6 @@ #include #include -/* The list of all DCBs */ -static LIST_CONFIG DCBlist = -{LIST_TYPE_RECYCLABLE, sizeof(DCB), SPINLOCK_INIT}; - /* A DCB with null values, used for initialization */ static DCB dcb_initialized = DCB_INIT; @@ -193,17 +188,6 @@ bool dcb_get_ses_log_info( return false; } -/* - * @brief Pre-allocate memory for a number of DCBs - * - * @param The number of DCBs to be pre-allocated - */ -bool -dcb_pre_alloc(int number) -{ - return list_pre_alloc(&DCBlist, number, dcb_initialize); -} - /** * @brief Initialize a DCB * @@ -252,7 +236,6 @@ dcb_alloc(dcb_role_t role, SERV_LISTENER *listener) dcb_initialize(newdcb); newdcb->dcb_role = role; newdcb->listener = listener; - newdcb->entry_is_ready = true; return newdcb; } @@ -1832,6 +1815,11 @@ spin_reporter(void *dcb, char *desc, int value) dcb_printf((DCB *)dcb, "\t\t%-40s %d\n", desc, value); } +bool printAllDCBs_cb(DCB *dcb, void *data) +{ + printDCB(dcb); + return true; +} /** * Diagnostic to print all DCB allocated in the system @@ -1839,15 +1827,7 @@ spin_reporter(void *dcb, char *desc, int value) */ void printAllDCBs() { - list_entry_t *current; - - current = list_start_iteration(&DCBlist); - - while (current) - { - printDCB((DCB *)current); - current = list_iterate(&DCBlist, current); - } + dcb_foreach(printAllDCBs_cb, NULL); } /** @@ -2663,6 +2643,57 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) return count; } +struct dcb_usage_count +{ + int count; + DCB_USAGE type; +}; + +bool count_by_usage_cb(DCB *dcb, void *data) +{ + struct dcb_usage_count *d = (struct dcb_usage_count*)data; + + switch (d->type) + { + case DCB_USAGE_CLIENT: + if (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role) + { + d->count++; + } + break; + case DCB_USAGE_LISTENER: + if (dcb->state == DCB_STATE_LISTENING) + { + d->count++; + } + break; + case DCB_USAGE_BACKEND: + if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER) + { + d->count++; + } + break; + case DCB_USAGE_INTERNAL: + if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER || + dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER) + { + d->count++; + } + break; + case DCB_USAGE_ZOMBIE: + if (DCB_ISZOMBIE(dcb)) + { + d->count++; + } + break; + case DCB_USAGE_ALL: + d->count++; + break; + } + + return true; +} + /** * Return DCB counts optionally filtered by usage * @@ -2672,55 +2703,11 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) int dcb_count_by_usage(DCB_USAGE usage) { - int rval = 0; - DCB *dcb; - list_entry_t *current; + struct dcb_usage_count val = {.count = 0, .type = usage}; - current = list_start_iteration(&DCBlist); + dcb_foreach(count_by_usage_cb, &val); - while (current) - { - dcb = (DCB *)current; - switch (usage) - { - case DCB_USAGE_CLIENT: - if (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role) - { - rval++; - } - break; - case DCB_USAGE_LISTENER: - if (dcb->state == DCB_STATE_LISTENING) - { - rval++; - } - break; - case DCB_USAGE_BACKEND: - if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER) - { - rval++; - } - break; - case DCB_USAGE_INTERNAL: - if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER || - dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER) - { - rval++; - } - break; - case DCB_USAGE_ZOMBIE: - if (DCB_ISZOMBIE(dcb)) - { - rval++; - } - break; - case DCB_USAGE_ALL: - rval++; - break; - } - current = list_iterate(&DCBlist, current); - } - return rval; + return val.count; } /** diff --git a/server/core/gateway.cc b/server/core/gateway.cc index de8096f98..f2808c328 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -1935,11 +1935,6 @@ int main(int argc, char **argv) goto return_main; } - /* Temporary - should use configuration values and test return value (bool) - * TODO: Enable the list manager code */ - dcb_pre_alloc(1); - session_pre_alloc(1); - /** Initialize statistics */ ts_stats_init(); diff --git a/server/core/session.c b/server/core/session.c index 38bcbd8b3..4b01cf781 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -44,10 +43,6 @@ #include #include -/* This list of all sessions */ -LIST_CONFIG SESSIONlist = -{LIST_TYPE_RECYCLABLE, sizeof(SESSION), SPINLOCK_INIT}; - /* A session with null values, used for initialization */ static SESSION session_initialized = SESSION_INIT; @@ -62,7 +57,6 @@ static void session_simple_free(SESSION *session, DCB *dcb); static void session_add_to_all_list(SESSION *session); static SESSION *session_find_free(); static void session_final_free(SESSION *session); -static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESSIONLISTFILTER filter); /** * @brief Initialize a session @@ -83,17 +77,6 @@ session_initialize(void *session) *(SESSION *)session = session_initialized; } -/* - * @brief Pre-allocate memory for a number of sessions - * - * @param The number of sessions to be pre-allocated - */ -bool -session_pre_alloc(int number) -{ - return list_pre_alloc(&SESSIONlist, number, session_initialize); -} - /** * Allocate a new session for a new client of the specified service. * @@ -220,7 +203,6 @@ session_alloc(SERVICE *service, DCB *client_dcb) CHK_SESSION(session); client_dcb->session = session; - session->entry_is_ready = true; return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session; } @@ -238,8 +220,6 @@ session_set_dummy(DCB *client_dcb) SESSION *session; session = &session_dummy_struct; - session->list_entry_chk_top = CHK_NUM_MANAGED_LIST; - session->list_entry_chk_tail = CHK_NUM_MANAGED_LIST; session->ses_chk_top = CHK_NUM_SESSION; session->ses_chk_tail = CHK_NUM_SESSION; session->ses_is_child = false; @@ -252,7 +232,6 @@ session_set_dummy(DCB *client_dcb) session->state = SESSION_STATE_DUMMY; session->refcount = 1; session->ses_id = 0; - session->next = NULL; client_dcb->session = session; return session; @@ -448,20 +427,7 @@ session_final_free(SESSION *session) int session_isvalid(SESSION *session) { - int rval = 0; - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - if ((SESSION *)current == session) - { - rval = 1; - list_terminate_iteration_early(&SESSIONlist, current); - break; - } - current = list_iterate(&SESSIONlist, current); - } - - return rval; + return true; } /** @@ -479,8 +445,19 @@ printSession(SESSION *session) printf("\tState: %s\n", session_state(session->state)); printf("\tService: %s (%p)\n", session->service->name, session->service); printf("\tClient DCB: %p\n", session->client_dcb); - printf("\tConnected: %s", + printf("\tConnected: %s\n", asctime_r(localtime_r(&session->stats.connect, &result), timebuf)); + printf("\tRouter Session: %p\n", session->router_session); +} + +bool printAllSessions_cb(DCB *dcb, void *data) +{ + if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER) + { + printSession(dcb->session); + } + + return true; } /** @@ -492,76 +469,7 @@ printSession(SESSION *session) void printAllSessions() { - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - printSession((SESSION *)current); - current = list_iterate(&SESSIONlist, current); - } -} - - -/** - * Check sessions - * - * Designed to be called within a debugger session in order - * to display information regarding "interesting" sessions - */ -void -CheckSessions() -{ - list_entry_t *current; - int noclients = 0; - int norouter = 0; - - current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *list_session = (SESSION *)current; - if (list_session->state != SESSION_STATE_LISTENER || - list_session->state != SESSION_STATE_LISTENER_STOPPED) - { - if (list_session->client_dcb == NULL && list_session->refcount) - { - if (noclients == 0) - { - printf("Sessions without a client DCB.\n"); - printf("==============================\n"); - } - printSession(list_session); - noclients++; - } - } - current = list_iterate(&SESSIONlist, current); - } - if (noclients) - { - printf("%d Sessions have no clients\n", noclients); - } - current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *list_session = (SESSION *)current; - if (list_session->state != SESSION_STATE_LISTENER || - list_session->state != SESSION_STATE_LISTENER_STOPPED) - { - if (list_session->router_session == NULL && list_session->refcount) - { - if (norouter == 0) - { - printf("Sessions without a router session.\n"); - printf("==================================\n"); - } - printSession(list_session); - norouter++; - } - } - current = list_iterate(&SESSIONlist, current); - } - if (norouter) - { - printf("%d Sessions have no router session\n", norouter); - } + dcb_foreach(printAllSessions_cb, NULL); } /* @@ -572,7 +480,17 @@ CheckSessions() void dprintSessionList(DCB *pdcb) { - dprintListStats(pdcb, &SESSIONlist, "All Sessions"); +} + +/** Callback for dprintAllSessions */ +bool dprintAllSessions_cb(DCB *dcb, void *data) +{ + if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER) + { + DCB *out_dcb = (DCB*)data; + dprintSession(out_dcb, dcb->session); + } + return true; } /** @@ -586,14 +504,8 @@ dprintSessionList(DCB *pdcb) void dprintAllSessions(DCB *dcb) { - - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - dprintSession(dcb, (SESSION *)current); - current = list_iterate(&SESSIONlist, current); - } - } + dcb_foreach(dprintAllSessions_cb, dcb); +} /** * Print a particular session to a DCB @@ -646,6 +558,22 @@ dprintSession(DCB *dcb, SESSION *print_session) } } +bool dListSessions_cb(DCB *dcb, void *data) +{ + if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER) + { + DCB *out_dcb = (DCB*)data; + SESSION *session = dcb->session; + dcb_printf(out_dcb, "%-16p | %-15s | %-14s | %s\n", session, + session->client_dcb && session->client_dcb->remote ? + session->client_dcb->remote : "", + session->service && session->service->name ? + session->service->name : "", + session_state(session->state)); + } + + return true; +} /** * List all sessions in tabular form to a DCB * @@ -657,32 +585,13 @@ dprintSession(DCB *dcb, SESSION *print_session) void dListSessions(DCB *dcb) { - bool written_heading = false; - list_entry_t *current = list_start_iteration(&SESSIONlist); - if (current) - { - dcb_printf(dcb, "Sessions.\n"); - dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); - dcb_printf(dcb, "Session | Client | Service | State\n"); - dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); - written_heading = true; - } - while (current) - { - SESSION *list_session = (SESSION *)current; - dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", list_session, - ((list_session->client_dcb && list_session->client_dcb->remote) - ? list_session->client_dcb->remote : ""), - (list_session->service && list_session->service->name ? list_session->service->name - : ""), - session_state(list_session->state)); - current = list_iterate(&SESSIONlist, current); - } - if (written_heading) - { - dcb_printf(dcb, - "-----------------+-----------------+----------------+--------------------------\n\n"); - } + dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); + dcb_printf(dcb, "Session | Client | Service | State\n"); + dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); + + dcb_foreach(dListSessions_cb, dcb); + + dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n\n"); } /** @@ -719,28 +628,6 @@ session_state(session_state_t state) } } -/* - * @brief Find the session that relates to a given router session - * - * @param rses A router session - * @return The related session, or NULL if none - */ -SESSION* get_session_by_router_ses(void* rses) -{ - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - if (((SESSION *)current)->router_session == rses) - { - list_terminate_iteration_early(&SESSIONlist, current); - return (SESSION *)current; - } - current = list_iterate(&SESSIONlist, current); - } - return NULL; -} - - /** * Create the filter chain for this session. * @@ -892,9 +779,44 @@ session_getUser(SESSION *session) typedef struct { int index; + int current; SESSIONLISTFILTER filter; + RESULT_ROW *row; + RESULTSET *set; } SESSIONFILTER; +bool dcb_iter_cb(DCB *dcb, void *data) +{ + SESSIONFILTER *cbdata = (SESSIONFILTER*)data; + + if (cbdata->current < cbdata->index) + { + if (cbdata->filter == SESSION_LIST_ALL || + (cbdata->filter == SESSION_LIST_CONNECTION && + (dcb->session->state != SESSION_STATE_LISTENER))) + { + cbdata->current++; + } + } + else + { + char buf[20]; + SESSION *list_session = dcb->session; + + cbdata->index++; + cbdata->row = resultset_make_row(cbdata->set); + snprintf(buf, sizeof(buf), "%p", list_session); + resultset_row_set(cbdata->row, 0, buf); + resultset_row_set(cbdata->row, 1, ((list_session->client_dcb && list_session->client_dcb->remote) + ? list_session->client_dcb->remote : "")); + resultset_row_set(cbdata->row, 2, (list_session->service && list_session->service->name + ? list_session->service->name : "")); + resultset_row_set(cbdata->row, 3, session_state(list_session->state)); + return false; + } + return true; +} + /** * Provide a row to the result set that defines the set of sessions * @@ -905,74 +827,18 @@ typedef struct static RESULT_ROW * sessionRowCallback(RESULTSET *set, void *data) { - SESSIONFILTER *cbdata = (SESSIONFILTER *)data; - int i = 0; - list_entry_t *current = list_start_iteration(&SESSIONlist); + SESSIONFILTER *cbdata = (SESSIONFILTER*)data; + RESULT_ROW *row = NULL; - /* Skip to the first non-listener if not showing listeners */ - current = skip_maybe_to_next_non_listener(current, cbdata->filter); + dcb_foreach(dcb_iter_cb, cbdata); - while (i < cbdata->index && current) + if (cbdata->row) { - if (cbdata->filter == SESSION_LIST_ALL || - (cbdata->filter == SESSION_LIST_CONNECTION && - ((SESSION *)current)->state != SESSION_STATE_LISTENER)) - { - i++; - } - current = list_iterate(&SESSIONlist, current); + row = cbdata->row; + cbdata->row = NULL; } - /* Skip to the next non-listener if not showing listeners */ - current = skip_maybe_to_next_non_listener(current, cbdata->filter); - - if (NULL == current) - { - MXS_FREE(data); - return NULL; - } - else - { - char buf[20]; - RESULT_ROW *row; - SESSION *list_session = (SESSION *)current; - - cbdata->index++; - row = resultset_make_row(set); - snprintf(buf,19, "%p", list_session); - buf[19] = '\0'; - resultset_row_set(row, 0, buf); - resultset_row_set(row, 1, ((list_session->client_dcb && list_session->client_dcb->remote) - ? list_session->client_dcb->remote : "")); - resultset_row_set(row, 2, (list_session->service && list_session->service->name - ? list_session->service->name : "")); - resultset_row_set(row, 3, session_state(list_session->state)); - list_terminate_iteration_early(&SESSIONlist, current); - return row; - } -} - -/* - * @brief Skip to the next non-listener session, if not showing listeners - * - * Based on a test of the filter that is the second parameter, along with the - * state of the sessions. - * - * @param current The session to start the possible skipping - * @param filter The filter the defines the operation - * - * @result The first session beyond those skipped, or the starting session; - * NULL if the list of sessions is exhausted. - */ -static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESSIONLISTFILTER filter) -{ - /* Skip to the first non-listener if not showing listeners */ - while (current && filter == SESSION_LIST_CONNECTION && - ((SESSION *)current)->state == SESSION_STATE_LISTENER) - { - current = list_iterate(&SESSIONlist, current); - } - return current; + return row; } /** @@ -985,6 +851,7 @@ static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESS * so we suppress the warning. In fact, the function call results in return * of the set structure which includes a pointer to data */ + /*lint -e429 */ RESULTSET * sessionGetList(SESSIONLISTFILTER filter) @@ -998,11 +865,16 @@ sessionGetList(SESSIONLISTFILTER filter) } data->index = 0; data->filter = filter; + data->current = 0; + data->row = NULL; + if ((set = resultset_create(sessionRowCallback, data)) == NULL) { MXS_FREE(data); return NULL; } + + data->set = set; resultset_add_column(set, "Session", 16, COL_TYPE_VARCHAR); resultset_add_column(set, "Client", 15, COL_TYPE_VARCHAR); resultset_add_column(set, "Service", 15, COL_TYPE_VARCHAR); diff --git a/server/modules/filter/tee/tee.c b/server/modules/filter/tee/tee.c index d979f2e47..ab91bfd3a 100644 --- a/server/modules/filter/tee/tee.c +++ b/server/modules/filter/tee/tee.c @@ -213,8 +213,6 @@ int route_single_query(TEE_INSTANCE* my_instance, int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer); void create_orphan(SESSION* ses); -extern LIST_CONFIG SESSIONlist; - static void orphan_free(void* data) { @@ -299,7 +297,7 @@ orphan_free(void* data) tmp->session->router_session); tmp->session->state = SESSION_STATE_FREE; - list_free_entry(&SESSIONlist, (list_entry_t*)tmp->session); + MXS_FREE(tmp->session); MXS_FREE(tmp); } diff --git a/server/modules/routing/debugcli/debugcmd.c b/server/modules/routing/debugcli/debugcmd.c index 9505346e3..2f15c5e6c 100644 --- a/server/modules/routing/debugcli/debugcmd.c +++ b/server/modules/routing/debugcli/debugcmd.c @@ -92,8 +92,6 @@ #define ARG_TYPE_FILTER 9 #define ARG_TYPE_NUMERIC 10 -extern LIST_CONFIG SESSIONlist; - /** * The subcommand structure * @@ -2115,6 +2113,31 @@ static bool get_log_action(const char* name, struct log_action_entry* entryp) return found; } + +bool seslog_cb(DCB *dcb, void *data) +{ + bool rval = true; + struct log_action_entry *entry = ((void**)data)[0]; + size_t *id = ((void**)data)[1]; + bool enable = (bool)((void**)data)[2]; + SESSION *session = dcb->session; + + if (session->ses_id == *id) + { + if (enable) + { + session_enable_log_priority(session, entry->priority); + } + else + { + session_disable_log_priority(session, entry->priority); + } + rval = false; + } + + return rval; +} + /** * Enables a log for a single session * @param session The session in question @@ -2127,21 +2150,10 @@ static void enable_sess_log_action(DCB *dcb, char *arg1, char *arg2) if (get_log_action(arg1, &entry)) { - size_t id = (size_t) strtol(arg2, 0, 0); - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *session = (SESSION *)current; - if (session->ses_id == id) - { - session_enable_log_priority(session, entry.priority); - list_terminate_iteration_early(&SESSIONlist, current); - break; - } - current = list_iterate(&SESSIONlist, current); - } + size_t id = (size_t)strtol(arg2, NULL, 10); + void *data[] = {&entry, &id, (void*)true}; - if (!current) + if (dcb_foreach(seslog_cb, data)) { dcb_printf(dcb, "Session not found: %s.\n", arg2); } @@ -2164,28 +2176,17 @@ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2) if (get_log_action(arg1, &entry)) { - size_t id = (size_t) strtol(arg2, 0, 0); - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *session = (SESSION *)current; - if (session->ses_id == id) - { - session_disable_log_priority(session, entry.priority); - list_terminate_iteration_early(&SESSIONlist, current); - break; - } - current = list_iterate(&SESSIONlist, current); - } + size_t id = (size_t)strtol(arg2, NULL, 10); + void *data[] = {&entry, &id, (void*)false}; - if (!current) + if (dcb_foreach(seslog_cb, data)) { dcb_printf(dcb, "Session not found: %s.\n", arg2); } } else { - dcb_printf(dcb, "%s is not supported for disable log.\n", arg1); + dcb_printf(dcb, "%s is not supported for enable log.\n", arg1); } } @@ -2226,6 +2227,30 @@ static int string_to_priority(const char* name) return result ? result->priority : -1; } +bool sesprio_cb(DCB *dcb, void *data) +{ + bool rval = true; + int *priority = ((void**)data)[0]; + size_t *id = ((void**)data)[1]; + bool enable = (bool)((void**)data)[2]; + SESSION *session = dcb->session; + + if (session->ses_id == *id) + { + if (enable) + { + session_enable_log_priority(session, *priority); + } + else + { + session_disable_log_priority(session, *priority); + } + rval = false; + } + + return rval; +} + /** * Enables a log priority for a single session * @param session The session in question @@ -2238,21 +2263,10 @@ static void enable_sess_log_priority(DCB *dcb, char *arg1, char *arg2) if (priority != -1) { - size_t id = (size_t) strtol(arg2, 0, 0); - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *session = (SESSION *)current; - if (session->ses_id == id) - { - session_enable_log_priority(session, priority); - list_terminate_iteration_early(&SESSIONlist, current); - break; - } - current = list_iterate(&SESSIONlist, current); - } + size_t id = (size_t) strtol(arg2, NULL, 10); + void *data[] = {&priority, &id, (void*)true}; - if (!current) + if (dcb_foreach(sesprio_cb, data)) { dcb_printf(dcb, "Session not found: %s.\n", arg2); } @@ -2275,21 +2289,10 @@ static void disable_sess_log_priority(DCB *dcb, char *arg1, char *arg2) if (priority != -1) { - size_t id = (size_t) strtol(arg2, 0, 0); - list_entry_t *current = list_start_iteration(&SESSIONlist); - while (current) - { - SESSION *session = (SESSION *)current; - if (session->ses_id == id) - { - session_disable_log_priority(session, priority); - list_terminate_iteration_early(&SESSIONlist, current); - break; - } - current = list_iterate(&SESSIONlist, current); - } + size_t id = (size_t) strtol(arg2, NULL, 10); + void *data[] = {&priority, &id, (void*)false}; - if (!current) + if (dcb_foreach(seslog_cb, data)) { dcb_printf(dcb, "Session not found: %s.\n", arg2); }