/** * event-handler thread * */ void *chassis_event_thread_loop(chassis_event_thread_t *thread) { cur_thid = thread->index; gboolean has_no_active_con = FALSE; /** * check once a second if we shall shutdown the proxy */ while (!chassis_is_shutdown_immediate() && (!chassis_is_shutdown_normal() || !has_no_active_con)) { struct timeval timeout; int r; /* check exit status */ if (chassis_is_shutdown_normal()) { if (thread->connection_nums == 0) { has_no_active_con = TRUE; g_log_dbproxy(g_debug, "no connection in thread %d", thread->index); continue; } } if (!chassis_is_shutdown_immediate()) { chassis_event_thread_update_conn_status(thread); } timeout.tv_sec = 1; timeout.tv_usec = 0; g_assert(event_base_loopexit(thread->event_base, &timeout) == 0); r = event_base_dispatch(thread->event_base); if (r == -1) { #ifdef WIN32 errno = WSAGetLastError(); #endif if (errno == EINTR) continue; g_log_dbproxy(g_critical, "leaving chassis_event_thread_loop early, errno != EINTR was: %s (%d)", g_strerror(errno), errno); break; } } g_log_dbproxy(g_message, "work thread %d will exit", thread->index); g_atomic_int_set(&thread->exit_phase, EVENT_THREAD_EXITED); return NULL; }
static void chassis_event_thread_update_conn_status(chassis_event_thread_t *thread) { network_mysqld_con *conn = NULL; GList *gl_conn = NULL; network_mysqld_con_lua_t *st = NULL; g_assert(thread != NULL); gl_conn = thread->connection_list; while (gl_conn) { conn = gl_conn->data; st = conn->plugin_con_state; if (chassis_is_shutdown_normal() && g_atomic_int_get(&conn->conn_status.exit_phase) != CON_EXIT_TX) { g_atomic_int_set(&conn->conn_status.exit_begin_time, time(NULL)); g_atomic_int_set(&conn->conn_status.exit_phase, CON_EXIT_TX); } if (g_atomic_int_get(&conn->conn_status.exit_phase) == CON_EXIT_KILL || g_atomic_int_get(&conn->conn_status.exit_phase) == CON_EXIT_TX) { /*|| (st != NULL && st->backend != NULL && IS_BACKEND_WAITING_EXIT(st->backend)))*/ struct event *ev = NULL; gchar *event_msg = NULL; int pending = event_pending(&conn->client->event, EV_READ|EV_WRITE|EV_TIMEOUT, NULL); if (pending) { ev = &conn->client->event; event_msg = "client"; } else { pending = event_pending(&conn->server->event, EV_READ|EV_WRITE|EV_TIMEOUT, NULL); ev = &conn->server->event; event_msg = "server"; } if (pending != 0) { /* * 1 stands for the times of calling callback function after manual active event, * this parameter has been obsoleted at libevent-2.0. */ g_log_dbproxy(g_debug, "pending %s's %d event", event_msg, pending); event_active(ev, pending, 1); } } gl_conn = g_list_next(gl_conn); } }
gboolean chassis_is_shutdown() { return (chassis_is_shutdown_normal() || chassis_is_shutdown_immediate()); }