|  |  | @ -7,15 +7,9 @@ | 
			
		
	
		
			
				
					|  |  |  | #include <sql_connect.h>
 | 
			
		
	
		
			
				
					|  |  |  | #include <sql_audit.h>
 | 
			
		
	
		
			
				
					|  |  |  | #include <debug_sync.h>
 | 
			
		
	
		
			
				
					|  |  |  | #include <threadpool.h>
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | extern bool login_connection(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | extern bool do_command(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | extern void prepare_new_connection_state(THD* thd); | 
			
		
	
		
			
				
					|  |  |  | extern void end_connection(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | extern void thd_cleanup(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | extern void delete_thd(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /* Threadpool parameters */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | uint threadpool_min_threads; | 
			
		
	
	
		
			
				
					|  |  | @ -27,14 +21,15 @@ uint threadpool_oversubscribe; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | extern "C" pthread_key(struct st_my_thread_var*, THR_KEY_mysys); | 
			
		
	
		
			
				
					|  |  |  | extern bool do_command(THD*); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |   Worker threads contexts, and THD contexts. | 
			
		
	
		
			
				
					|  |  |  |   ===================================== | 
			
		
	
		
			
				
					|  |  |  |   ========================================= | 
			
		
	
		
			
				
					|  |  |  |    | 
			
		
	
		
			
				
					|  |  |  |   Both worker threads and connections have their sets of thread local variables  | 
			
		
	
		
			
				
					|  |  |  |   At the moment it is mysys_var (which has e.g dbug my_error and similar  | 
			
		
	
		
			
				
					|  |  |  |   goodies inside), and PSI per-client structure. | 
			
		
	
		
			
				
					|  |  |  |   At the moment it is mysys_var (this has specific data for dbug, my_error and  | 
			
		
	
		
			
				
					|  |  |  |   similar goodies), and PSI per-client structure. | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   Whenever query is executed following needs to be done: | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -77,7 +72,7 @@ struct Worker_thread_context | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |   Attach/associate the connection with the OS thread, | 
			
		
	
		
			
				
					|  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  | static inline bool thread_attach(THD* thd) | 
			
		
	
		
			
				
					|  |  |  | static bool thread_attach(THD* thd) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |   pthread_setspecific(THR_KEY_mysys,thd->mysys_var); | 
			
		
	
		
			
				
					|  |  |  |   thd->thread_stack=(char*)&thd; | 
			
		
	
	
		
			
				
					|  |  | @ -95,11 +90,10 @@ int threadpool_add_connection(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |   worker_context.save(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   /*
 | 
			
		
	
		
			
				
					|  |  |  |     Create a new connection context: mysys_thread_var and PSI thread  | 
			
		
	
		
			
				
					|  |  |  |     Store them in thd->mysys_var and thd->scheduler.m_psi. | 
			
		
	
		
			
				
					|  |  |  |     Create a new connection context: mysys_thread_var and PSI thread | 
			
		
	
		
			
				
					|  |  |  |     Store them in THD. | 
			
		
	
		
			
				
					|  |  |  |   */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   /* Use my_thread_init() to create new mysys_thread_var. */ | 
			
		
	
		
			
				
					|  |  |  |   pthread_setspecific(THR_KEY_mysys, 0); | 
			
		
	
		
			
				
					|  |  |  |   my_thread_init(); | 
			
		
	
		
			
				
					|  |  |  |   thd->mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); | 
			
		
	
	
		
			
				
					|  |  | @ -125,21 +119,29 @@ int threadpool_add_connection(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |   thd->start_utime= now; | 
			
		
	
		
			
				
					|  |  |  |   thd->thr_create_utime= now; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   if (setup_connection_thread_globals(thd) == 0) | 
			
		
	
		
			
				
					|  |  |  |   if (!setup_connection_thread_globals(thd)) | 
			
		
	
		
			
				
					|  |  |  |   { | 
			
		
	
		
			
				
					|  |  |  |     if (login_connection(thd) == 0) | 
			
		
	
		
			
				
					|  |  |  |     if (!login_connection(thd)) | 
			
		
	
		
			
				
					|  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |        prepare_new_connection_state(thd); | 
			
		
	
		
			
				
					|  |  |  |        retval = thd_is_connection_alive(thd)?0:-1; | 
			
		
	
		
			
				
					|  |  |  |        thd->net.reading_or_writing= 1; | 
			
		
	
		
			
				
					|  |  |  |       prepare_new_connection_state(thd); | 
			
		
	
		
			
				
					|  |  |  |        | 
			
		
	
		
			
				
					|  |  |  |       /* 
 | 
			
		
	
		
			
				
					|  |  |  |         Check if THD is ok, as prepare_new_connection_state() | 
			
		
	
		
			
				
					|  |  |  |         can fail, for example if init command failed. | 
			
		
	
		
			
				
					|  |  |  |       */ | 
			
		
	
		
			
				
					|  |  |  |       if (thd_is_connection_alive(thd)) | 
			
		
	
		
			
				
					|  |  |  |       { | 
			
		
	
		
			
				
					|  |  |  |         retval= 0; | 
			
		
	
		
			
				
					|  |  |  |         thd->net.reading_or_writing= 1; | 
			
		
	
		
			
				
					|  |  |  |         thd->skip_wait_timeout= true;       | 
			
		
	
		
			
				
					|  |  |  |       } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |   thd->skip_wait_timeout= true; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   worker_context.restore(); | 
			
		
	
		
			
				
					|  |  |  |   return retval; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | void threadpool_remove_connection(THD *thd) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -147,9 +149,7 @@ void threadpool_remove_connection(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |   worker_context.save(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   thread_attach(thd); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   thd->killed= KILL_CONNECTION; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   thd->net.reading_or_writing= 0; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   end_connection(thd); | 
			
		
	
	
		
			
				
					|  |  | @ -163,11 +163,13 @@ void threadpool_remove_connection(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |   mysql_mutex_unlock(&LOCK_thread_count); | 
			
		
	
		
			
				
					|  |  |  |   mysql_cond_broadcast(&COND_thread_count); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   /* Free resources (thread_var and PSI connection specific struct)*/ | 
			
		
	
		
			
				
					|  |  |  |   /*
 | 
			
		
	
		
			
				
					|  |  |  |     Free resources associated with this connection:  | 
			
		
	
		
			
				
					|  |  |  |     mysys thread_var and PSI thread. | 
			
		
	
		
			
				
					|  |  |  |   */ | 
			
		
	
		
			
				
					|  |  |  |   my_thread_end(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   worker_context.restore(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | int threadpool_process_request(THD *thd) | 
			
		
	
	
		
			
				
					|  |  | @ -181,8 +183,8 @@ int threadpool_process_request(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |   if (thd->killed >= KILL_CONNECTION) | 
			
		
	
		
			
				
					|  |  |  |   { | 
			
		
	
		
			
				
					|  |  |  |     /* 
 | 
			
		
	
		
			
				
					|  |  |  |       kill flag can be set have been killed by  | 
			
		
	
		
			
				
					|  |  |  |       timeout handler or by a KILL command | 
			
		
	
		
			
				
					|  |  |  |       killed flag was set by timeout handler  | 
			
		
	
		
			
				
					|  |  |  |       or KILL command. Return error. | 
			
		
	
		
			
				
					|  |  |  |     */ | 
			
		
	
		
			
				
					|  |  |  |     worker_context.restore(); | 
			
		
	
		
			
				
					|  |  |  |     return 1; | 
			
		
	
	
		
			
				
					|  |  | @ -206,33 +208,18 @@ int threadpool_process_request(THD *thd) | 
			
		
	
		
			
				
					|  |  |  |     vio= thd->net.vio; | 
			
		
	
		
			
				
					|  |  |  |     if (!vio->has_data(vio)) | 
			
		
	
		
			
				
					|  |  |  |     {  | 
			
		
	
		
			
				
					|  |  |  |       /*
 | 
			
		
	
		
			
				
					|  |  |  |         More info on this debug sync is in sql_parse.cc | 
			
		
	
		
			
				
					|  |  |  |       */ | 
			
		
	
		
			
				
					|  |  |  |       /* More info on this debug sync is in sql_parse.cc*/ | 
			
		
	
		
			
				
					|  |  |  |       DEBUG_SYNC(thd, "before_do_command_net_read"); | 
			
		
	
		
			
				
					|  |  |  |       thd->net.reading_or_writing= 1; | 
			
		
	
		
			
				
					|  |  |  |       break; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |   if (!retval) | 
			
		
	
		
			
				
					|  |  |  |     thd->net.reading_or_writing= 1; | 
			
		
	
		
			
				
					|  |  |  |   }  | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |   worker_context.restore(); | 
			
		
	
		
			
				
					|  |  |  |   return retval; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |   Scheduler struct, individual functions are implemented | 
			
		
	
		
			
				
					|  |  |  |   in threadpool_unix.cc or threadpool_win.cc | 
			
		
	
		
			
				
					|  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | extern bool tp_init(); | 
			
		
	
		
			
				
					|  |  |  | extern void tp_add_connection(THD*); | 
			
		
	
		
			
				
					|  |  |  | extern void tp_wait_begin(THD *, int); | 
			
		
	
		
			
				
					|  |  |  | extern void tp_wait_end(THD*); | 
			
		
	
		
			
				
					|  |  |  | extern void tp_post_kill_notification(THD *thd); | 
			
		
	
		
			
				
					|  |  |  | extern void tp_end(void); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static scheduler_functions tp_scheduler_functions= | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |   0,                                  // max_threads
 | 
			
		
	
	
		
			
				
					|  |  | @ -255,7 +242,7 @@ void pool_of_threads_scheduler(struct scheduler_functions *func, | 
			
		
	
		
			
				
					|  |  |  |     uint *arg_connection_count) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |   *func = tp_scheduler_functions; | 
			
		
	
		
			
				
					|  |  |  |   func->max_threads= *arg_max_connections + 1; | 
			
		
	
		
			
				
					|  |  |  |   func->max_threads= threadpool_max_threads; | 
			
		
	
		
			
				
					|  |  |  |   func->max_connections= arg_max_connections; | 
			
		
	
		
			
				
					|  |  |  |   func->connection_count= arg_connection_count; | 
			
		
	
		
			
				
					|  |  |  |   scheduler_init(); | 
			
		
	
	
		
			
				
					|  |  | 
 |