From ea1cb87b0e1273a9e2ba08db93f520ed36026860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 18 Aug 2015 20:10:16 +0000 Subject: [PATCH] Improved handling of PROXYSQL STOP and PROXYSQL START Not perfect implementation . See issue #336 for more details --- include/MySQL_Thread.h | 1 + lib/MySQL_Thread.cpp | 23 +++++++++++++++++------ lib/ProxySQL_Admin.cpp | 2 ++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 74a5310bd..83b6ecf63 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -313,6 +313,7 @@ class MySQL_Threads_Handler int listener_del(const char *iface); int listener_del(const char *address, int port); void start_listeners(); + void stop_listeners(); void signal_all_threads(unsigned char _c=0); SQLite3_result * SQL3_Processlist(); bool kill_session(uint32_t _thread_session_id); diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 43103e392..8d4e48e66 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -286,7 +286,7 @@ int MySQL_Threads_Handler::listener_del(const char *iface) { } for (i=0;imypolls.pending_listener_del,0)); + while(__sync_fetch_and_add(&thr->mypolls.pending_listener_del,0)); } MLM->del(idx); shutdown(fd,SHUT_RDWR); @@ -1003,6 +1003,17 @@ void MySQL_Threads_Handler::start_listeners() { free_tokenizer( &tok ); } +void MySQL_Threads_Handler::stop_listeners() { + if (variables.interfaces==NULL || strlen(variables.interfaces)==0) + return; + tokenizer_t tok = tokenizer( variables.interfaces, ";", TOKENIZER_NO_EMPTIES ); + const char* token; + for (token = tokenize( &tok ); token; token = tokenize( &tok )) { + listener_del((char *)token); + } + free_tokenizer( &tok ); +} + MySQL_Threads_Handler::~MySQL_Threads_Handler() { if (variables.connect_timeout_server_error) free(variables.connect_timeout_server_error); if (variables.default_schema) free(variables.default_schema); @@ -1289,11 +1300,6 @@ void MySQL_Thread::run() { } - while ((n=__sync_add_and_fetch(&mypolls.pending_listener_del,0))) { // spin here - poll_listener_del(n); - assert(__sync_bool_compare_and_swap(&mypolls.pending_listener_del,n,0)); - } - //this is the only portion of code not protected by a global mutex //proxy_debug(PROXY_DEBUG_NET,5,"Calling poll with timeout %d\n", ( mypolls.poll_timeout ? mypolls.poll_timeout : mysql_thread___poll_timeout ) ); proxy_debug(PROXY_DEBUG_NET,5,"Calling poll with timeout %d\n", ( mypolls.poll_timeout ? ( mypolls.poll_timeout/1000 > (unsigned int) mysql_thread___poll_timeout ? mypolls.poll_timeout/1000 : mysql_thread___poll_timeout ) : mysql_thread___poll_timeout ) ); @@ -1301,6 +1307,11 @@ void MySQL_Thread::run() { rc=poll(mypolls.fds,mypolls.len, ( mypolls.poll_timeout ? ( mypolls.poll_timeout/1000 < (unsigned int) mysql_thread___poll_timeout ? mypolls.poll_timeout/1000 : mysql_thread___poll_timeout ) : mysql_thread___poll_timeout ) ); proxy_debug(PROXY_DEBUG_NET,5,"%s\n", "Returning poll"); + while ((n=__sync_add_and_fetch(&mypolls.pending_listener_del,0))) { // spin here + poll_listener_del(n); + assert(__sync_bool_compare_and_swap(&mypolls.pending_listener_del,n,0)); + } + curtime=monotonic_time(); spin_wrlock(&thread_mutex); diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 4fba9e6fe..da5b18a15 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -309,6 +309,8 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_ if (query_no_space_length==strlen("PROXYSQL STOP") && !strncasecmp("PROXYSQL STOP",query_no_space, query_no_space_length)) { proxy_info("Received PROXYSQL STOP command\n"); + GloMTH->signal_all_threads(10); + GloMTH->stop_listeners(); __sync_bool_compare_and_swap(&glovars.shutdown,0,1); glovars.reload=2; return false;