@@ -608,6 +608,7 @@ void THD::enter_stage(const PSI_stage_info *new_stage,
608608
609609 m_current_stage_key = new_stage->m_key ;
610610 set_proc_info (msg);
611+ store_cached_properties (cached_properties::RW_STATUS);
611612
612613 m_stage_progress_psi =
613614 MYSQL_SET_STAGE (m_current_stage_key, calling_file, calling_line);
@@ -870,7 +871,7 @@ THD::THD(bool enable_plugins)
870871 protocol_text->init (this );
871872 protocol_binary->init (this );
872873 protocol_text->set_client_capabilities (0 ); // minimalistic client
873- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
874+ store_cached_properties ( );
874875
875876 /*
876877 Make sure thr_lock_info_init() is called for threads which do not get
@@ -907,6 +908,22 @@ THD::THD(bool enable_plugins)
907908 }
908909}
909910
911+ void THD::store_cached_properties (cached_properties prop_mask) {
912+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
913+ { assert (current_thd == this ); });
914+
915+ auto is_selected = [this , prop_mask](cached_properties property) -> bool {
916+ return (this ->m_protocol != nullptr &&
917+ static_cast <int >(prop_mask) & static_cast <int >(property));
918+ };
919+
920+ if (is_selected (cached_properties::IS_ALIVE))
921+ m_cached_is_connection_alive.store (m_protocol->connection_alive ());
922+
923+ if (is_selected (cached_properties::RW_STATUS))
924+ m_cached_rw_status.store (m_protocol->get_rw_status ());
925+ }
926+
910927void THD::copy_table_access_properties (THD *thd) {
911928 thread_stack = thd->thread_stack ;
912929 variables.option_bits = thd->variables .option_bits & OPTION_BIN_LOG;
@@ -1427,7 +1444,7 @@ void THD::release_resources() {
14271444 if (is_classic_protocol () && get_protocol_classic ()->get_vio ()) {
14281445 vio_delete (get_protocol_classic ()->get_vio ());
14291446 get_protocol_classic ()->end_net ();
1430- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
1447+ store_cached_properties ( );
14311448 }
14321449
14331450 /* modification plan for UPDATE/DELETE should be freed. */
@@ -1732,6 +1749,8 @@ void THD::disconnect(bool server_shutdown) {
17321749 /* Disconnect even if a active vio is not associated. */
17331750 if (is_classic_protocol () && get_protocol_classic ()->get_vio () != vio &&
17341751 get_protocol_classic ()->connection_alive ()) {
1752+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
1753+ { assert (current_thd == this ); });
17351754 m_protocol->shutdown (server_shutdown);
17361755 }
17371756 }
@@ -2341,6 +2360,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
23412360 backup->examined_row_count = m_examined_row_count;
23422361 backup->sent_row_count = m_sent_row_count;
23432362 backup->num_truncated_fields = num_truncated_fields;
2363+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
2364+ { assert (current_thd == this ); });
23442365 backup->client_capabilities = m_protocol->get_client_capabilities ();
23452366 backup->savepoints = get_transaction ()->m_savepoints ;
23462367 backup->first_successful_insert_id_in_prev_stmt =
@@ -2913,6 +2934,8 @@ bool THD::send_result_metadata(const mem_root_deque<Item *> &list, uint flags) {
29132934 DBUG_TRACE;
29142935 uchar buff[MAX_FIELD_WIDTH];
29152936 String tmp ((char *)buff, sizeof (buff), &my_charset_bin);
2937+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
2938+ { assert (current_thd == this ); });
29162939
29172940 if (m_protocol->start_result_metadata (CountVisibleFields (list), flags,
29182941 variables.character_set_results ))
@@ -2953,6 +2976,8 @@ bool THD::send_result_set_row(const mem_root_deque<Item *> &row_items) {
29532976 String str_buffer (buffer, sizeof (buffer), &my_charset_bin);
29542977
29552978 DBUG_TRACE;
2979+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
2980+ { assert (current_thd == this ); });
29562981
29572982 for (Item *item : VisibleFields (row_items)) {
29582983 if (item->send (m_protocol, &str_buffer) || is_error ()) return true ;
@@ -2970,6 +2995,8 @@ void THD::send_statement_status() {
29702995 assert (!get_stmt_da ()->is_sent ());
29712996 bool error = false ;
29722997 Diagnostics_area *da = get_stmt_da ();
2998+ DBUG_EXECUTE_IF (" assert_only_current_thd_protocol_access" ,
2999+ { assert (current_thd == this ); });
29733000
29743001 /* Can not be true, but do not take chances in production. */
29753002 if (da->is_sent ()) return ;
@@ -3270,14 +3297,16 @@ bool THD::is_connected(bool use_cached_connection_alive) {
32703297 return get_protocol ()->connection_alive ();
32713298}
32723299
3300+ uint THD::get_protocol_rw_status () { return m_cached_rw_status.load (); }
3301+
32733302Protocol *THD::get_protocol () {
3274- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
3303+ store_cached_properties ( );
32753304 return m_protocol;
32763305}
32773306
32783307Protocol_classic *THD::get_protocol_classic () {
32793308 assert (is_classic_protocol ());
3280- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
3309+ store_cached_properties ( );
32813310 return pointer_cast<Protocol_classic *>(m_protocol);
32823311}
32833312
@@ -3286,14 +3315,14 @@ void THD::push_protocol(Protocol *protocol) {
32863315 assert (protocol != nullptr );
32873316 m_protocol->push_protocol (protocol);
32883317 m_protocol = protocol;
3289- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
3318+ store_cached_properties ( );
32903319}
32913320
32923321void THD::pop_protocol () {
32933322 assert (m_protocol != nullptr );
32943323 m_protocol = m_protocol->pop_protocol ();
32953324 assert (m_protocol != nullptr );
3296- m_cached_is_connection_alive. store (m_protocol-> connection_alive () );
3325+ store_cached_properties ( );
32973326}
32983327
32993328void THD::set_time () {
0 commit comments