#ifndef __CLASS_MYSQL_THREAD_H #define __CLASS_MYSQL_THREAD_H #define ____CLASS_STANDARD_MYSQL_THREAD_H #include "proxysql.h" #include "cpp.h" #define MIN_POLL_LEN 8 #define MIN_POLL_DELETE_RATIO 8 #define ADMIN_HOSTGROUP -2 #define STATS_HOSTGROUP -3 static unsigned int near_pow_2 (unsigned int n) { unsigned int i = 1; while (i < n) i <<= 1; return i ? i : n; } class ProxySQL_Poll { private: void shrink() { unsigned int new_size=near_pow_2(len+1); fds=(struct pollfd *)realloc(fds,new_size*sizeof(struct pollfd)); myds=(MySQL_Data_Stream **)realloc(myds,new_size*sizeof(MySQL_Data_Stream *)); last_recv=(unsigned long long *)realloc(last_recv,new_size*sizeof(unsigned long long)); last_sent=(unsigned long long *)realloc(last_sent,new_size*sizeof(unsigned long long)); size=new_size; }; void expand(unsigned int more) { if ( (len+more) > size ) { unsigned int new_size=near_pow_2(len+more); fds=(struct pollfd *)realloc(fds,new_size*sizeof(struct pollfd)); myds=(MySQL_Data_Stream **)realloc(myds,new_size*sizeof(MySQL_Data_Stream *)); last_recv=(unsigned long long *)realloc(last_recv,new_size*sizeof(unsigned long long)); last_sent=(unsigned long long *)realloc(last_sent,new_size*sizeof(unsigned long long)); size=new_size; } }; public: unsigned int poll_timeout; unsigned long loops; StatCounters *loop_counters; unsigned int len; unsigned int size; struct pollfd *fds; MySQL_Data_Stream **myds; unsigned long long *last_recv; unsigned long long *last_sent; volatile int pending_listener_add; volatile int pending_listener_del; ProxySQL_Poll() { loop_counters=new StatCounters(15,10,false); poll_timeout=0; loops=0; len=0; pending_listener_add=0; pending_listener_del=0; size=MIN_POLL_LEN; fds=(struct pollfd *)malloc(size*sizeof(struct pollfd)); myds=(MySQL_Data_Stream **)malloc(size*sizeof(MySQL_Data_Stream *)); last_recv=(unsigned long long *)malloc(size*sizeof(unsigned long long)); last_sent=(unsigned long long *)malloc(size*sizeof(unsigned long long)); }; ~ProxySQL_Poll() { unsigned int i; for (i=0;imyds_type==MYDS_LISTENER) { delete myds[i]; } } free(myds); free(fds); free(last_recv); free(last_sent); delete loop_counters; }; void add(uint32_t _events, int _fd, MySQL_Data_Stream *_myds, unsigned long long sent_time) { if (len==size) { expand(1); } myds[len]=_myds; fds[len].fd=_fd; fds[len].events=_events; fds[len].revents=0; if (_myds) { _myds->mypolls=this; _myds->poll_fds_idx=len; // fix a serious bug } last_recv[len]=monotonic_time(); last_sent[len]=sent_time; len++; }; void remove_index_fast(unsigned int i) { if ((int)i==-1) return; myds[i]->poll_fds_idx=-1; // this prevents further delete if (i != (len-1)) { myds[i]=myds[len-1]; fds[i].fd=fds[len-1].fd; fds[i].events=fds[len-1].events; fds[i].revents=fds[len-1].revents; myds[i]->poll_fds_idx=i; // fix a serious bug last_recv[i]=last_recv[len-1]; last_sent[i]=last_sent[len-1]; } len--; if ( ( len>MIN_POLL_LEN ) && ( size > len*MIN_POLL_DELETE_RATIO ) ) { shrink(); } }; int find_index(int fd) { unsigned int i; for (i=0; i