diff --git a/include/query_processor.h b/include/query_processor.h index 7b089cff2..99331f062 100644 --- a/include/query_processor.h +++ b/include/query_processor.h @@ -63,6 +63,7 @@ class Query_Processor { virtual SQLite3_result * get_current_query_rules() {return NULL;}; virtual SQLite3_result * get_stats_query_rules() {return NULL;}; + virtual void update_query_processor_stats() {}; }; diff --git a/lib/Standard_MySQL_Thread.cpp b/lib/Standard_MySQL_Thread.cpp index 96499b739..2889130cf 100644 --- a/lib/Standard_MySQL_Thread.cpp +++ b/lib/Standard_MySQL_Thread.cpp @@ -534,6 +534,9 @@ virtual void run() { int loops=0; // FIXME: debug + unsigned long oldtime=monotonic_time(); + unsigned long curtime=monotonic_time(); + while (shutdown==0) { for (n = 0; n < mypolls.len; n++) { @@ -547,10 +550,19 @@ virtual void run() { if (loops>100) { loops-=10; } + + proxy_debug(PROXY_DEBUG_NET,5,"%s\n", "Calling poll"); rc=poll(mypolls.fds,mypolls.len,mysql_thread___poll_timeout); proxy_debug(PROXY_DEBUG_NET,5,"%s\n", "Returning poll"); + + curtime=monotonic_time(); + if (curtime>oldtime+mysql_thread___poll_timeout) { + oldtime=curtime; + GloQPro->update_query_processor_stats(); + } + if (rc == -1 && errno == EINTR) // poll() timeout, try again continue; diff --git a/lib/Standard_Query_Processor.cpp b/lib/Standard_Query_Processor.cpp index a50a46fc5..05e526896 100644 --- a/lib/Standard_Query_Processor.cpp +++ b/lib/Standard_Query_Processor.cpp @@ -420,6 +420,7 @@ virtual QP_out_t * process_mysql_query(MySQL_Session *sess, void *ptr, unsigned qr->hits++; // this is done without atomic function because it updates only the local variables //ret=(QP_out_t *)malloc(sizeof(QP_out_t)); +/* { // FIXME: this block of code is only for testing if ((qr->hits%20)==0) { @@ -427,6 +428,7 @@ virtual QP_out_t * process_mysql_query(MySQL_Session *sess, void *ptr, unsigned if (__sync_add_and_fetch(&version,0) == _thr_SQP_version) { // extra safety check to avoid race conditions __sync_fetch_and_add(&qr->parent->hits,20); } +*/ /* QP_rule_t *qrg; for (std::vector::iterator it=rules.begin(); it!=rules.end(); ++it) { @@ -437,10 +439,11 @@ virtual QP_out_t * process_mysql_query(MySQL_Session *sess, void *ptr, unsigned } } */ +/* spin_rdunlock(&rwlock); } } - +*/ if (qr->flagOUT >= 0) { proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "query rule %d has changed flagOUT\n", qr->rule_id); flagIN=qr->flagOUT; @@ -480,6 +483,30 @@ virtual void delete_QP_out(QP_out_t *o) { l_free(sizeof(QP_out_t),o); }; +virtual void update_query_processor_stats() { + // Note: + // this function is called by each thread to update global query statistics + // + // As an extra safety, it checks that the version didn't change + // Yet, if version changed doesn't perfomr any rules update + // + // It acquires a read lock to ensure that the rules table doesn't change + // Yet, because it has to update vales, it uses atomic operations + proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Updating query rules statistics\n"); + spin_rdlock(&rwlock); + if (__sync_add_and_fetch(&version,0) == _thr_SQP_version) { + QP_rule_t *qr; + for (std::vector::iterator it=_thr_SQP_rules->begin(); it!=_thr_SQP_rules->end(); ++it) { + qr=*it; + if (qr->active && qr->hits) { + __sync_fetch_and_add(&qr->parent->hits,qr->hits); + qr->hits=0; + } + } + } + spin_rdunlock(&rwlock); +} + }; extern "C" Query_Processor * create_Query_Processor_func() {