1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| pthread_handler_t handle_one_connection(void *arg) { thread_scheduler.init_new_connection_thread(); // 初始化线程预处理操作 setup_connection_thread_globals(thd); //载入一些Session级变量 for (;;) { lex_start(thd); //初始化LEX词法解析器 login_connection(thd); // 进行连接身份验证 prepare_new_connection_state(thd); // 初始化线程Status,即show status看到的 do_command(thd); // 处理命令 end_connection(thd); //没事做了关闭连接,丢入线程池 } }
void do_handle_one_connection(THD *thd_arg) { THD *thd= thd_arg;
thd->thr_create_utime= my_micro_time(); // 更新thd 时间
//// 初始化线程预处理操作 if (MYSQL_CALLBACK_ELSE(thd->scheduler, init_new_connection_thread, (), 0)) { close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); MYSQL_CALLBACK(thd->scheduler, end_thread, (thd, 0)); return; }
/* If a thread was created to handle this connection: increment slow_launch_threads counter if it took more than slow_launch_time seconds to create the thread. */ if (thd->prior_thr_create_utime) { ulong launch_time= (ulong) (thd->thr_create_utime - thd->prior_thr_create_utime); if (launch_time >= slow_launch_time*1000000L) statistic_increment(slow_launch_threads, &LOCK_status); thd->prior_thr_create_utime= 0; }
/* handle_one_connection() is normally the only way a thread would start and would always be on the very high end of the stack , therefore, the thread stack always starts at the address of the first local variable of handle_one_connection, which is thd. We need to know the start of the stack so that we could check for stack overruns. */ thd->thread_stack= (char*) &thd; if (setup_connection_thread_globals(thd)) return;
for (;;) { bool rc;
thd->ppi_thread= PPI_THREAD_CALL(create_thread)(); thd->ppi_transaction= PPI_THREAD_CALL(get_transaction_context)(thd->ppi_thread);
NET *net= &thd->net; mysql_socket_set_thread_owner(net->vio->mysql_socket);
//// 准备connection rc= thd_prepare_connection(thd); if (rc) goto end_thread;
while (thd_is_connection_alive(thd)) { mysql_audit_release(thd); if (do_command(thd)) break; } end_connection(thd);
end_thread: close_connection(thd); if (MYSQL_CALLBACK_ELSE(thd->scheduler, end_thread, (thd, 1), 0)) return; // Probably no-threads
/* If end_thread() returns, we are either running with thread-handler=no-threads or this thread has been schedule to handle the next connection. */ thd= current_thd; thd->thread_stack= (char*) &thd; } }
|