/* Copyright(C) 2019, 2020, MariaDB * * This program is free software; you can redistribute itand /or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ #if defined (HAVE_POOL_OF_THREADS) #include #include #include #include #include #include #ifdef _WIN32 #include #include "threadpool_winsockets.h" /* AIX may define this, too ?*/ #define HAVE_IOCP #endif #ifdef _WIN32 typedef HANDLE TP_file_handle; #else typedef int TP_file_handle; #define INVALID_HANDLE_VALUE -1 #endif #ifdef __linux__ #include typedef struct epoll_event native_event; #elif defined(HAVE_KQUEUE) #include typedef struct kevent native_event; #elif defined (__sun) #include typedef port_event_t native_event; #elif defined (HAVE_IOCP) typedef OVERLAPPED_ENTRY native_event; #else #error threadpool is not available on this platform #endif struct thread_group_t; /* Per-thread structure for workers */ struct worker_thread_t { ulonglong event_count; /* number of request handled by this thread */ thread_group_t* thread_group; worker_thread_t* next_in_list; worker_thread_t** prev_in_list; mysql_cond_t cond; bool woken; }; typedef I_P_List, I_P_List_counter > worker_list_t; struct TP_connection_generic :public TP_connection { TP_connection_generic(CONNECT* c); ~TP_connection_generic(); int init() override { return 0; } void set_io_timeout(int sec) override; int start_io() override; void wait_begin(int type) override; void wait_end() override; thread_group_t* thread_group; TP_connection_generic* next_in_queue; TP_connection_generic** prev_in_queue; ulonglong abs_wait_timeout; ulonglong enqueue_time; TP_file_handle fd; bool bound_to_poll_descriptor; int waiting; bool fix_group; #ifdef _WIN32 win_aiosocket win_sock{}; void init_vio(st_vio *vio) override { win_sock.init(vio);} #endif }; typedef I_P_List, I_P_List_counter, I_P_List_fast_push_back > connection_queue_t; const int NQUEUES = 2; /* We have high and low priority queues*/ enum class operation_origin { WORKER, LISTENER }; struct thread_group_counters_t { ulonglong thread_creations; ulonglong thread_creations_due_to_stall; ulonglong wakes; ulonglong wakes_due_to_stall; ulonglong throttles; ulonglong stalls; ulonglong dequeues[2]; ulonglong polls[2]; }; struct thread_group_t { mysql_mutex_t mutex; connection_queue_t queues[NQUEUES]; worker_list_t waiting_threads; worker_thread_t* listener; pthread_attr_t* pthread_attr; TP_file_handle pollfd; int thread_count; int active_thread_count; int connection_count; /* Stats for the deadlock detection timer routine.*/ int io_event_count; int queue_event_count; ulonglong last_thread_creation_time; int shutdown_pipe[2]; bool shutdown; bool stalled; thread_group_counters_t counters; char pad[CPU_LEVEL1_DCACHE_LINESIZE]; }; #define TP_INCREMENT_GROUP_COUNTER(group,var) do {group->counters.var++;}while(0) extern thread_group_t* all_groups; #endif