#include "mysql_priv.h"#include <hash.h>#include <assert.h>Include dependency graph for lock.cc:

Go to the source code of this file.
| #define GET_LOCK_STORE_LOCKS 2 |
| #define GET_LOCK_UNLOCK 1 |
Definition at line 76 of file lock.cc.
Referenced by mysql_lock_abort(), mysql_lock_abort_for_thread(), and mysql_unlock_some_tables().
| #define GOT_GLOBAL_READ_LOCK 1 |
Definition at line 1177 of file lock.cc.
Referenced by lock_global_read_lock(), and make_global_read_lock_block_commit().
| #define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2 |
Definition at line 1178 of file lock.cc.
Referenced by make_global_read_lock_block_commit(), and unlock_global_read_lock().
| #define must_wait |
Value:
(global_read_lock && \ (is_not_commit || \ global_read_lock_blocks_commit))
Definition at line 1243 of file lock.cc.
Referenced by wait_if_global_read_lock().
| void broadcast_refresh | ( | void | ) |
Definition at line 1379 of file lock.cc.
References COND_global_read_lock, COND_refresh, and VOID.
Referenced by close_cached_table(), close_thread_tables(), drop_locked_tables(), mysql_ha_close(), mysql_ha_flush_table(), remove_table_from_cache(), reopen_table(), reopen_tables(), unlock_table_name(), and unlock_table_names().
01380 { 01381 VOID(pthread_cond_broadcast(&COND_refresh)); 01382 VOID(pthread_cond_broadcast(&COND_global_read_lock)); 01383 }
Here is the caller graph for this function:

| static MYSQL_LOCK * get_lock_data | ( | THD * | thd, | |
| TABLE ** | table, | |||
| uint | count, | |||
| uint | flags, | |||
| TABLE ** | write_locked | |||
| ) | [static] |
Definition at line 668 of file lock.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table::file, LOGGER::get_general_log_thd(), LOGGER::get_slow_log_thd(), handler::lock_count(), logger, TMP_TABLE, and to.
Referenced by mysql_lock_abort(), mysql_lock_abort_for_thread(), mysql_lock_downgrade_write(), mysql_lock_tables(), and mysql_unlock_some_tables().
00670 { 00671 uint i,tables,lock_count; 00672 MYSQL_LOCK *sql_lock; 00673 THR_LOCK_DATA **locks, **locks_buf, **locks_start; 00674 TABLE **to, **table_buf; 00675 DBUG_ENTER("get_lock_data"); 00676 00677 DBUG_PRINT("info", ("count %d", count)); 00678 *write_lock_used=0; 00679 for (i=tables=lock_count=0 ; i < count ; i++) 00680 { 00681 if (table_ptr[i]->s->tmp_table != TMP_TABLE) 00682 { 00683 tables+=table_ptr[i]->file->lock_count(); 00684 lock_count++; 00685 } 00686 /* 00687 Check if we can lock the table. For some tables we cannot do that 00688 beacause of handler-specific locking issues. 00689 */ 00690 if (!table_ptr[i]-> file-> 00691 check_if_locking_is_allowed(thd->lex->sql_command, thd->lex->type, 00692 table_ptr[i], count, 00693 (thd == logger.get_general_log_thd()) || 00694 (thd == logger.get_slow_log_thd()))) 00695 DBUG_RETURN(0); 00696 } 00697 00698 /* 00699 Allocating twice the number of pointers for lock data for use in 00700 thr_mulit_lock(). This function reorders the lock data, but cannot 00701 update the table values. So the second part of the array is copied 00702 from the first part immediately before calling thr_multi_lock(). 00703 */ 00704 if (!(sql_lock= (MYSQL_LOCK*) 00705 my_malloc(sizeof(*sql_lock) + 00706 sizeof(THR_LOCK_DATA*) * tables * 2 + 00707 sizeof(table_ptr) * lock_count, 00708 MYF(0)))) 00709 DBUG_RETURN(0); 00710 locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1); 00711 to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2); 00712 sql_lock->table_count=lock_count; 00713 sql_lock->lock_count=tables; 00714 DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d", 00715 sql_lock->table_count, sql_lock->lock_count)); 00716 00717 for (i=0 ; i < count ; i++) 00718 { 00719 TABLE *table; 00720 enum thr_lock_type lock_type; 00721 00722 if ((table=table_ptr[i])->s->tmp_table == TMP_TABLE) 00723 continue; 00724 lock_type= table->reginfo.lock_type; 00725 if (lock_type >= TL_WRITE_ALLOW_WRITE) 00726 { 00727 *write_lock_used=table; 00728 if (table->db_stat & HA_READ_ONLY) 00729 { 00730 my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); 00731 /* Clear the lock type of the lock data that are stored already. */ 00732 sql_lock->lock_count= locks - sql_lock->locks; 00733 reset_lock_data(sql_lock); 00734 my_free((gptr) sql_lock,MYF(0)); 00735 DBUG_RETURN(0); 00736 } 00737 } 00738 THR_LOCK_DATA **org_locks = locks; 00739 locks_start= locks; 00740 locks= table->file->store_lock(thd, locks, 00741 (flags & GET_LOCK_UNLOCK) ? TL_IGNORE : 00742 lock_type); 00743 if (flags & GET_LOCK_STORE_LOCKS) 00744 { 00745 table->lock_position= (uint) (to - table_buf); 00746 table->lock_data_start= (uint) (locks_start - locks_buf); 00747 table->lock_count= (uint) (locks - locks_start); 00748 } 00749 *to++= table; 00750 if (locks) 00751 for ( ; org_locks != locks ; org_locks++) 00752 (*org_locks)->debug_print_param= (void *) table; 00753 } 00754 DBUG_RETURN(sql_lock); 00755 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int lock_and_wait_for_table_name | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 822 of file lock.cc.
References DBUG_ENTER, DBUG_RETURN, error, LOCK_open, lock_table_name(), pthread_mutex_lock, pthread_mutex_unlock, start_waiting_global_read_lock(), TRUE, unlock_table_name(), VOID, wait_for_locked_table_names(), and wait_if_global_read_lock().
Referenced by LOGGER::deactivate_log_handler(), LOGGER::flush_logs(), mysql_create_like_table(), mysql_truncate(), prepare_for_repair(), and prepare_for_restore().
00823 { 00824 int lock_retcode; 00825 int error= -1; 00826 DBUG_ENTER("lock_and_wait_for_table_name"); 00827 00828 if (wait_if_global_read_lock(thd, 0, 1)) 00829 DBUG_RETURN(1); 00830 VOID(pthread_mutex_lock(&LOCK_open)); 00831 if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0) 00832 goto end; 00833 if (lock_retcode && wait_for_locked_table_names(thd, table_list)) 00834 { 00835 unlock_table_name(thd, table_list); 00836 goto end; 00837 } 00838 error=0; 00839 00840 end: 00841 pthread_mutex_unlock(&LOCK_open); 00842 start_waiting_global_read_lock(thd); 00843 DBUG_RETURN(error); 00844 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 230 of file lock.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, error, F_RDLCK, F_UNLCK, F_WRLCK, HA_BLOCK_LOCK, HA_READ_ONLY, print_lock_error(), reg1, TL_READ, and TL_READ_NO_INSERT.
Referenced by mysql_lock_tables().
00231 { 00232 reg1 uint i; 00233 int lock_type,error; 00234 DBUG_ENTER("lock_external"); 00235 00236 DBUG_PRINT("info", ("count %d", count)); 00237 for (i=1 ; i <= count ; i++, tables++) 00238 { 00239 DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ); 00240 lock_type=F_WRLCK; /* Lock exclusive */ 00241 if ((*tables)->db_stat & HA_READ_ONLY || 00242 ((*tables)->reginfo.lock_type >= TL_READ && 00243 (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT)) 00244 lock_type=F_RDLCK; 00245 if ((error=(*tables)->file->ha_external_lock(thd,lock_type))) 00246 { 00247 print_lock_error(error, (*tables)->file->table_type()); 00248 for (; i-- ; tables--) 00249 { 00250 (*tables)->file->ha_external_lock(thd, F_UNLCK); 00251 (*tables)->current_lock=F_UNLCK; 00252 } 00253 DBUG_RETURN(error); 00254 } 00255 else 00256 { 00257 (*tables)->db_stat &= ~ HA_BLOCK_LOCK; 00258 (*tables)->current_lock= lock_type; 00259 } 00260 } 00261 DBUG_RETURN(0); 00262 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool lock_global_read_lock | ( | THD * | thd | ) |
Definition at line 1180 of file lock.cc.
References COND_global_read_lock, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, GOT_GLOBAL_READ_LOCK, LOCK_global_read_lock, and pthread_mutex_lock.
Referenced by reload_acl_and_cache().
01181 { 01182 DBUG_ENTER("lock_global_read_lock"); 01183 01184 if (!thd->global_read_lock) 01185 { 01186 const char *old_message; 01187 (void) pthread_mutex_lock(&LOCK_global_read_lock); 01188 old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, 01189 "Waiting to get readlock"); 01190 DBUG_PRINT("info", 01191 ("waiting_for: %d protect_against: %d", 01192 waiting_for_read_lock, protect_against_global_read_lock)); 01193 01194 waiting_for_read_lock++; 01195 while (protect_against_global_read_lock && !thd->killed) 01196 pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); 01197 waiting_for_read_lock--; 01198 if (thd->killed) 01199 { 01200 thd->exit_cond(old_message); 01201 DBUG_RETURN(1); 01202 } 01203 thd->global_read_lock= GOT_GLOBAL_READ_LOCK; 01204 global_read_lock++; 01205 thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock 01206 } 01207 /* 01208 We DON'T set global_read_lock_blocks_commit now, it will be set after 01209 tables are flushed (as the present function serves for FLUSH TABLES WITH 01210 READ LOCK only). Doing things in this order is necessary to avoid 01211 deadlocks (we must allow COMMIT until all tables are closed; we should not 01212 forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR 01213 UPDATE and one does FLUSH TABLES WITH READ LOCK). 01214 */ 01215 DBUG_RETURN(0); 01216 }
Here is the caller graph for this function:

| int lock_table_name | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| bool | check_in_use | |||
| ) |
Definition at line 874 of file lock.cc.
References create_table_def_key(), st_table_list::db, db, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, hash_first(), hash_next(), st_table::in_use, INTERNAL_TMP_TABLE, key, key_length, st_table::locked_by_name, MAX_DBKEY_LENGTH, my_free, my_hash_insert(), my_multi_malloc(), MY_WME, MY_ZEROFILL, MYF, NULL, open_cache, remove_table_from_cache(), st_table::s, st_table_list::table, st_table_list::table_name, test, and st_table_share::version.
Referenced by lock_and_wait_for_table_name(), lock_table_names(), and open_unireg_entry().
00875 { 00876 TABLE *table; 00877 TABLE_SHARE *share; 00878 char *key_buff; 00879 char key[MAX_DBKEY_LENGTH]; 00880 char *db= table_list->db; 00881 uint key_length; 00882 HASH_SEARCH_STATE state; 00883 DBUG_ENTER("lock_table_name"); 00884 DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name)); 00885 00886 key_length= create_table_def_key(thd, key, table_list, 0); 00887 00888 if (check_in_use) 00889 { 00890 /* Only insert the table if we haven't insert it already */ 00891 for (table=(TABLE*) hash_first(&open_cache, (byte*)key, 00892 key_length, &state); 00893 table ; 00894 table = (TABLE*) hash_next(&open_cache,(byte*) key, 00895 key_length, &state)) 00896 { 00897 if (table->in_use == thd) 00898 { 00899 DBUG_PRINT("info", ("Table is in use")); 00900 table->s->version= 0; // Ensure no one can use this 00901 table->locked_by_name= 1; 00902 DBUG_RETURN(0); 00903 } 00904 } 00905 } 00906 /* 00907 Create a table entry with the right key and with an old refresh version 00908 Note that we must use my_multi_malloc() here as this is freed by the 00909 table cache 00910 */ 00911 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), 00912 &table, sizeof(*table), 00913 &share, sizeof(*share), 00914 &key_buff, key_length, 00915 NULL)) 00916 DBUG_RETURN(-1); 00917 table->s= share; 00918 share->set_table_cache_key(key_buff, key, key_length); 00919 share->tmp_table= INTERNAL_TMP_TABLE; // for intern_close_table 00920 table->in_use= thd; 00921 table->locked_by_name=1; 00922 table_list->table=table; 00923 00924 if (my_hash_insert(&open_cache, (byte*) table)) 00925 { 00926 my_free((gptr) table,MYF(0)); 00927 DBUG_RETURN(-1); 00928 } 00929 00930 /* Return 1 if table is in use */ 00931 DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name, 00932 check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG))); 00933 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool lock_table_names | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 1007 of file lock.cc.
References lock_table(), lock_table_name(), TRUE, unlock_table_names(), and wait_for_locked_table_names().
Referenced by mysql_create_or_drop_trigger(), mysql_rename_tables(), and mysql_rm_table_part2().
01008 { 01009 bool got_all_locks=1; 01010 TABLE_LIST *lock_table; 01011 01012 for (lock_table= table_list; lock_table; lock_table= lock_table->next_local) 01013 { 01014 int got_lock; 01015 if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0) 01016 goto end; // Fatal error 01017 if (got_lock) 01018 got_all_locks=0; // Someone is using table 01019 } 01020 01021 /* If some table was in use, wait until we got the lock */ 01022 if (!got_all_locks && wait_for_locked_table_names(thd, table_list)) 01023 goto end; 01024 return 0; 01025 01026 end: 01027 unlock_table_names(thd, table_list, lock_table); 01028 return 1; 01029 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool locked_named_table | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) | [static] |
Definition at line 946 of file lock.cc.
References st_table::next, st_table_list::next_local, st_table_list::table, and table_is_used().
Referenced by wait_for_locked_table_names().
00947 { 00948 for (; table_list ; table_list=table_list->next_local) 00949 { 00950 TABLE *table= table_list->table; 00951 if (table) 00952 { 00953 TABLE *save_next= table->next; 00954 bool result; 00955 table->next= 0; 00956 result= table_is_used(table_list->table, 0); 00957 table->next= save_next; 00958 if (result) 00959 return 1; 00960 } 00961 } 00962 return 0; // All tables are locked 00963 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool make_global_read_lock_block_commit | ( | THD * | thd | ) |
Definition at line 1320 of file lock.cc.
References COND_global_read_lock, DBUG_ENTER, DBUG_EXECUTE_IF, DBUG_RETURN, error, GOT_GLOBAL_READ_LOCK, LOCK_global_read_lock, MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT, pthread_mutex_lock, and test.
Referenced by reload_acl_and_cache().
01321 { 01322 bool error; 01323 const char *old_message; 01324 DBUG_ENTER("make_global_read_lock_block_commit"); 01325 /* 01326 If we didn't succeed lock_global_read_lock(), or if we already suceeded 01327 make_global_read_lock_block_commit(), do nothing. 01328 */ 01329 if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK) 01330 DBUG_RETURN(0); 01331 pthread_mutex_lock(&LOCK_global_read_lock); 01332 /* increment this BEFORE waiting on cond (otherwise race cond) */ 01333 global_read_lock_blocks_commit++; 01334 /* For testing we set up some blocking, to see if we can be killed */ 01335 DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", 01336 protect_against_global_read_lock++;); 01337 old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, 01338 "Waiting for all running commits to finish"); 01339 while (protect_against_global_read_lock && !thd->killed) 01340 pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); 01341 DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", 01342 protect_against_global_read_lock--;); 01343 if ((error= test(thd->killed))) 01344 global_read_lock_blocks_commit--; // undo what we did 01345 else 01346 thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT; 01347 thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock 01348 DBUG_RETURN(error); 01349 }
Here is the caller graph for this function:

Definition at line 429 of file lock.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, get_lock_data(), GET_LOCK_UNLOCK, st_thr_lock_data::lock, st_mysql_lock::lock_count, st_mysql_lock::locks, my_free, MYF, and thr_abort_locks().
Referenced by abort_and_upgrade_lock(), abort_locked_tables(), close_old_data_files(), mysql_admin_table(), mysql_wait_completed_table(), and wait_while_table_is_used().
00430 { 00431 MYSQL_LOCK *locked; 00432 TABLE *write_lock_used; 00433 DBUG_ENTER("mysql_lock_abort"); 00434 00435 if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, 00436 &write_lock_used))) 00437 { 00438 for (uint i=0; i < locked->lock_count; i++) 00439 thr_abort_locks(locked->locks[i]->lock, upgrade_lock); 00440 my_free((gptr) locked,MYF(0)); 00441 } 00442 DBUG_VOID_RETURN; 00443 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 459 of file lock.cc.
References DBUG_ENTER, DBUG_RETURN, FALSE, get_lock_data(), GET_LOCK_UNLOCK, st_table::in_use, st_thr_lock_data::lock, st_mysql_lock::lock_count, st_mysql_lock::locks, my_free, MYF, thr_abort_locks_for_thread(), and TRUE.
Referenced by mysql_wait_completed_table(), and remove_table_from_cache().
00460 { 00461 MYSQL_LOCK *locked; 00462 TABLE *write_lock_used; 00463 bool result= FALSE; 00464 DBUG_ENTER("mysql_lock_abort_for_thread"); 00465 00466 if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK, 00467 &write_lock_used))) 00468 { 00469 for (uint i=0; i < locked->lock_count; i++) 00470 { 00471 if (thr_abort_locks_for_thread(locked->locks[i]->lock, 00472 table->in_use->real_id)) 00473 result= TRUE; 00474 } 00475 my_free((gptr) locked,MYF(0)); 00476 } 00477 DBUG_RETURN(result); 00478 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void mysql_lock_downgrade_write | ( | THD * | thd, | |
| TABLE * | table, | |||
| thr_lock_type | new_lock_type | |||
| ) |
Definition at line 413 of file lock.cc.
References get_lock_data(), st_mysql_lock::lock_count, st_mysql_lock::locks, my_free, MYF, and thr_downgrade_write_lock().
Referenced by close_open_tables_and_downgrade().
00415 { 00416 MYSQL_LOCK *locked; 00417 TABLE *write_lock_used; 00418 if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used))) 00419 { 00420 for (uint i=0; i < locked->lock_count; i++) 00421 thr_downgrade_write_lock(locked->locks[i], new_lock_type); 00422 my_free((gptr) locked,MYF(0)); 00423 } 00424 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE_LIST* mysql_lock_have_duplicate | ( | THD * | thd, | |
| TABLE_LIST * | needle, | |||
| TABLE_LIST * | haystack | |||
| ) |
Definition at line 547 of file lock.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table::lock_count, st_table::lock_data_start, st_table::lock_position, lock_tables, st_mysql_lock::locks, st_table_list::next_global, st_table_list::placeholder(), st_table::s, st_table_list::schema_table, st_mysql_lock::table, st_table_list::table, table2, st_mysql_lock::table_count, st_table_list::table_name, TMP_TABLE, and st_table_share::tmp_table.
Referenced by unique_table().
00549 { 00550 MYSQL_LOCK *mylock; 00551 TABLE **lock_tables; 00552 TABLE *table; 00553 TABLE *table2; 00554 THR_LOCK_DATA **lock_locks; 00555 THR_LOCK_DATA **table_lock_data; 00556 THR_LOCK_DATA **end_data; 00557 THR_LOCK_DATA **lock_data2; 00558 THR_LOCK_DATA **end_data2; 00559 DBUG_ENTER("mysql_lock_have_duplicate"); 00560 00561 /* 00562 Table may not be defined for derived or view tables. 00563 Table may not be part of a lock for delayed operations. 00564 */ 00565 if (! (table= needle->table) || ! table->lock_count) 00566 goto end; 00567 00568 /* A temporary table does not have locks. */ 00569 if (table->s->tmp_table == TMP_TABLE) 00570 goto end; 00571 00572 /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */ 00573 if (! (mylock= thd->lock ? thd->lock : thd->locked_tables)) 00574 goto end; 00575 00576 /* If we have less than two tables, we cannot have duplicates. */ 00577 if (mylock->table_count < 2) 00578 goto end; 00579 00580 lock_locks= mylock->locks; 00581 lock_tables= mylock->table; 00582 00583 /* Prepare table related variables that don't change in loop. */ 00584 DBUG_ASSERT((table->lock_position < mylock->table_count) && 00585 (table == lock_tables[table->lock_position])); 00586 table_lock_data= lock_locks + table->lock_data_start; 00587 end_data= table_lock_data + table->lock_count; 00588 00589 for (; haystack; haystack= haystack->next_global) 00590 { 00591 if (haystack->placeholder() || haystack->schema_table) 00592 continue; 00593 table2= haystack->table; 00594 if (table2->s->tmp_table == TMP_TABLE) 00595 continue; 00596 00597 /* All tables in list must be in lock. */ 00598 DBUG_ASSERT((table2->lock_position < mylock->table_count) && 00599 (table2 == lock_tables[table2->lock_position])); 00600 00601 for (lock_data2= lock_locks + table2->lock_data_start, 00602 end_data2= lock_data2 + table2->lock_count; 00603 lock_data2 < end_data2; 00604 lock_data2++) 00605 { 00606 THR_LOCK_DATA **lock_data; 00607 THR_LOCK *lock2= (*lock_data2)->lock; 00608 00609 for (lock_data= table_lock_data; 00610 lock_data < end_data; 00611 lock_data++) 00612 { 00613 if ((*lock_data)->lock == lock2) 00614 { 00615 DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name)); 00616 DBUG_RETURN(haystack); 00617 } 00618 } 00619 } 00620 } 00621 00622 end: 00623 DBUG_PRINT("info", ("no duplicate found")); 00624 DBUG_RETURN(NULL); 00625 }
Here is the call graph for this function:

Here is the caller graph for this function:

| MYSQL_LOCK* mysql_lock_merge | ( | MYSQL_LOCK * | a, | |
| MYSQL_LOCK * | b | |||
| ) |
Definition at line 481 of file lock.cc.
References DBUG_ENTER, DBUG_RETURN, st_mysql_lock::lock_count, st_mysql_lock::locks, memcpy, my_free, my_malloc(), MY_WME, MYF, st_mysql_lock::table, and st_mysql_lock::table_count.
Referenced by reopen_tables().
00482 { 00483 MYSQL_LOCK *sql_lock; 00484 TABLE **table, **end_table; 00485 DBUG_ENTER("mysql_lock_merge"); 00486 00487 if (!(sql_lock= (MYSQL_LOCK*) 00488 my_malloc(sizeof(*sql_lock)+ 00489 sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+ 00490 sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME)))) 00491 DBUG_RETURN(0); // Fatal error 00492 sql_lock->lock_count=a->lock_count+b->lock_count; 00493 sql_lock->table_count=a->table_count+b->table_count; 00494 sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1); 00495 sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count); 00496 memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks)); 00497 memcpy(sql_lock->locks+a->lock_count,b->locks, 00498 b->lock_count*sizeof(*b->locks)); 00499 memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table)); 00500 memcpy(sql_lock->table+a->table_count,b->table, 00501 b->table_count*sizeof(*b->table)); 00502 00503 /* 00504 Now adjust lock_position and lock_data_start for all objects that was 00505 moved in 'b' (as there is now all objects in 'a' before these). 00506 */ 00507 for (table= sql_lock->table + a->table_count, 00508 end_table= table + b->table_count; 00509 table < end_table; 00510 table++) 00511 { 00512 (*table)->lock_position+= a->table_count; 00513 (*table)->lock_data_start+= a->lock_count; 00514 } 00515 00516 /* Delete old, not needed locks */ 00517 my_free((gptr) a,MYF(0)); 00518 my_free((gptr) b,MYF(0)); 00519 DBUG_RETURN(sql_lock); 00520 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void mysql_lock_remove | ( | THD * | thd, | |
| MYSQL_LOCK * | locked, | |||
| TABLE * | table | |||
| ) |
Definition at line 353 of file lock.cc.
References bmove(), DBUG_ASSERT, st_mysql_lock::lock_count, st_table::lock_count, st_table::lock_data_start, st_table::lock_position, st_mysql_lock::locks, mysql_unlock_some_tables(), reg1, st_mysql_lock::table, and st_mysql_lock::table_count.
Referenced by close_data_tables(), close_old_data_files(), drop_locked_tables(), and unlink_open_table().
00354 { 00355 mysql_unlock_some_tables(thd, &table,1); 00356 if (locked) 00357 { 00358 reg1 uint i; 00359 for (i=0; i < locked->table_count; i++) 00360 { 00361 if (locked->table[i] == table) 00362 { 00363 uint j, removed_locks, old_tables; 00364 TABLE *tbl; 00365 uint lock_data_end; 00366 00367 DBUG_ASSERT(table->lock_position == i); 00368 00369 /* Decrement table_count in advance, making below expressions easier */ 00370 old_tables= --locked->table_count; 00371 00372 /* The table has 'removed_locks' lock data elements in locked->locks */ 00373 removed_locks= table->lock_count; 00374 00375 /* Move down all table pointers above 'i'. */ 00376 bmove((char*) (locked->table+i), 00377 (char*) (locked->table+i+1), 00378 (old_tables - i) * sizeof(TABLE*)); 00379 00380 lock_data_end= table->lock_data_start + table->lock_count; 00381 /* Move down all lock data pointers above 'table->lock_data_end-1' */ 00382 bmove((char*) (locked->locks + table->lock_data_start), 00383 (char*) (locked->locks + lock_data_end), 00384 (locked->lock_count - lock_data_end) * 00385 sizeof(THR_LOCK_DATA*)); 00386 00387 /* 00388 Fix moved table elements. 00389 lock_position is the index in the 'locked->table' array, 00390 it must be fixed by one. 00391 table->lock_data_start is pointer to the lock data for this table 00392 in the 'locked->locks' array, they must be fixed by 'removed_locks', 00393 the lock data count of the removed table. 00394 */ 00395 for (j= i ; j < old_tables; j++) 00396 { 00397 tbl= locked->table[j]; 00398 tbl->lock_position--; 00399 DBUG_ASSERT(tbl->lock_position == j); 00400 tbl->lock_data_start-= removed_locks; 00401 } 00402 00403 /* Finally adjust lock_count. */ 00404 locked->lock_count-= removed_locks; 00405 break; 00406 } 00407 } 00408 } 00409 }
Here is the call graph for this function:

Here is the caller graph for this function:

| MYSQL_LOCK* mysql_lock_tables | ( | THD * | thd, | |
| TABLE ** | tables, | |||
| uint | count, | |||
| uint | flags, | |||
| bool * | need_reopen | |||
| ) |
Definition at line 114 of file lock.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, FALSE, get_lock_data(), GET_LOCK_STORE_LOCKS, global_read_lock, int(), st_mysql_lock::lock_count, lock_external(), st_mysql_lock::locks, memcpy, my_error(), my_free, MYF, mysql_unlock_tables(), refresh_version, reset_lock_data(), thr_lock_errno_to_mysql, thr_multi_lock(), TRUE, wait_for_tables(), and wait_if_global_read_lock().
Referenced by create_table_from_items(), handle_delayed_insert(), lock_tables(), mysql_ha_read(), open_ltable(), open_proc_table_for_read(), and reopen_tables().
00116 { 00117 MYSQL_LOCK *sql_lock; 00118 TABLE *write_lock_used; 00119 int rc; 00120 DBUG_ENTER("mysql_lock_tables"); 00121 00122 *need_reopen= FALSE; 00123 00124 for (;;) 00125 { 00126 if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, 00127 &write_lock_used))) 00128 break; 00129 00130 if (global_read_lock && write_lock_used && 00131 ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) 00132 { 00133 /* 00134 Someone has issued LOCK ALL TABLES FOR READ and we want a write lock 00135 Wait until the lock is gone 00136 */ 00137 if (wait_if_global_read_lock(thd, 1, 1)) 00138 { 00139 /* Clear the lock type of all lock data to avoid reusage. */ 00140 reset_lock_data(sql_lock); 00141 my_free((gptr) sql_lock,MYF(0)); 00142 sql_lock=0; 00143 break; 00144 } 00145 if (thd->version != refresh_version) 00146 { 00147 /* Clear the lock type of all lock data to avoid reusage. */ 00148 reset_lock_data(sql_lock); 00149 my_free((gptr) sql_lock,MYF(0)); 00150 goto retry; 00151 } 00152 } 00153 00154 thd->proc_info="System lock"; 00155 DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); 00156 if (lock_external(thd, tables, count)) 00157 { 00158 /* Clear the lock type of all lock data to avoid reusage. */ 00159 reset_lock_data(sql_lock); 00160 my_free((gptr) sql_lock,MYF(0)); 00161 sql_lock=0; 00162 break; 00163 } 00164 thd->proc_info="Table lock"; 00165 DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); 00166 thd->locked=1; 00167 /* Copy the lock data array. thr_multi_lock() reorders its contens. */ 00168 memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, 00169 sql_lock->lock_count * sizeof(*sql_lock->locks)); 00170 /* Lock on the copied half of the lock data array. */ 00171 rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + 00172 sql_lock->lock_count, 00173 sql_lock->lock_count, 00174 thd->lock_id)]; 00175 if (rc > 1) /* a timeout or a deadlock */ 00176 { 00177 my_error(rc, MYF(0)); 00178 my_free((gptr) sql_lock,MYF(0)); 00179 sql_lock= 0; 00180 break; 00181 } 00182 else if (rc == 1) /* aborted */ 00183 { 00184 thd->some_tables_deleted=1; // Try again 00185 sql_lock->lock_count= 0; // Locks are already freed 00186 } 00187 else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) 00188 { 00189 thd->locked=0; 00190 break; 00191 } 00192 else if (!thd->open_tables) 00193 { 00194 // Only using temporary tables, no need to unlock 00195 thd->some_tables_deleted=0; 00196 thd->locked=0; 00197 break; 00198 } 00199 thd->proc_info=0; 00200 00201 /* some table was altered or deleted. reopen tables marked deleted */ 00202 mysql_unlock_tables(thd,sql_lock); 00203 thd->locked=0; 00204 retry: 00205 sql_lock=0; 00206 if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN) 00207 { 00208 *need_reopen= TRUE; 00209 break; 00210 } 00211 if (wait_for_tables(thd)) 00212 break; // Couldn't open tables 00213 } 00214 thd->proc_info=0; 00215 if (thd->killed) 00216 { 00217 thd->send_kill_message(); 00218 if (sql_lock) 00219 { 00220 mysql_unlock_tables(thd,sql_lock); 00221 sql_lock=0; 00222 } 00223 } 00224 00225 thd->lock_time(); 00226 DBUG_RETURN (sql_lock); 00227 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void mysql_unlock_read_tables | ( | THD * | thd, | |
| MYSQL_LOCK * | sql_lock | |||
| ) |
Definition at line 295 of file lock.cc.
References DBUG_ENTER, lock, st_mysql_lock::lock_count, st_mysql_lock::locks, swap_variables, TL_WRITE_ALLOW_READ, and st_thr_lock_data::type.
Referenced by JOIN::join_free().
00296 { 00297 uint i,found; 00298 DBUG_ENTER("mysql_unlock_read_tables"); 00299 00300 /* Move all write locks first */ 00301 THR_LOCK_DATA **lock=sql_lock->locks; 00302 for (i=found=0 ; i < sql_lock->lock_count ; i++) 00303 { 00304 if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ) 00305 { 00306 swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]); 00307 lock++; 00308 found++; 00309 } 00310 } 00311 /* unlock the read locked tables */ 00312 if (i != found) 00313 { 00314 thr_multi_unlock(lock,i-found); 00315 sql_lock->lock_count= found; 00316 } 00317 00318 /* Then do the same for the external locks */ 00319 /* Move all write locked tables first */ 00320 TABLE **table=sql_lock->table; 00321 for (i=found=0 ; i < sql_lock->table_count ; i++) 00322 { 00323 DBUG_ASSERT(sql_lock->table[i]->lock_position == i); 00324 if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ) 00325 { 00326 swap_variables(TABLE *, *table, sql_lock->table[i]); 00327 table++; 00328 found++; 00329 } 00330 } 00331 /* Unlock all read locked tables */ 00332 if (i != found) 00333 { 00334 VOID(unlock_external(thd,table,i-found)); 00335 sql_lock->table_count=found; 00336 } 00337 /* Fix the lock positions in TABLE */ 00338 table= sql_lock->table; 00339 found= 0; 00340 for (i= 0; i < sql_lock->table_count; i++) 00341 { 00342 TABLE *tbl= *table; 00343 tbl->lock_position= table - sql_lock->table; 00344 tbl->lock_data_start= found; 00345 found+= tbl->lock_count; 00346 table++; 00347 } 00348 DBUG_VOID_RETURN; 00349 }
Here is the caller graph for this function:

Definition at line 281 of file lock.cc.
References get_lock_data(), GET_LOCK_UNLOCK, and mysql_unlock_tables().
Referenced by mysql_lock_remove(), and JOIN::optimize().
00282 { 00283 MYSQL_LOCK *sql_lock; 00284 TABLE *write_lock_used; 00285 if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK, 00286 &write_lock_used))) 00287 mysql_unlock_tables(thd, sql_lock); 00288 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void mysql_unlock_tables | ( | THD * | thd, | |
| MYSQL_LOCK * | sql_lock | |||
| ) |
Definition at line 265 of file lock.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, st_mysql_lock::lock_count, st_mysql_lock::locks, my_free, MYF, st_mysql_lock::table, st_mysql_lock::table_count, thr_multi_unlock(), unlock_external(), and VOID.
Referenced by close_cached_table(), close_thread_tables(), handle_delayed_insert(), lock_tables(), mysql_delete(), mysql_execute_command(), mysql_insert(), mysql_load(), mysql_lock_tables(), and mysql_unlock_some_tables().
00266 { 00267 DBUG_ENTER("mysql_unlock_tables"); 00268 if (sql_lock->lock_count) 00269 thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); 00270 if (sql_lock->table_count) 00271 VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); 00272 my_free((gptr) sql_lock,MYF(0)); 00273 DBUG_VOID_RETURN; 00274 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void print_lock_error | ( | int | error, | |
| const char * | ||||
| ) | [static] |
Definition at line 1065 of file lock.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, ER_CANT_LOCK, ER_ILLEGAL_HA, ER_LOCK_DEADLOCK, ER_LOCK_WAIT_TIMEOUT, ER_READ_ONLY_TRANSACTION, HA_ERR_LOCK_DEADLOCK, HA_ERR_LOCK_WAIT_TIMEOUT, HA_ERR_READ_ONLY_TRANSACTION, HA_ERR_WRONG_COMMAND, ME_BELL, ME_OLDWIN, ME_WAITTANG, my_error(), and MYF.
Referenced by lock_external(), and unlock_external().
01066 { 01067 int textno; 01068 DBUG_ENTER("print_lock_error"); 01069 01070 switch (error) { 01071 case HA_ERR_LOCK_WAIT_TIMEOUT: 01072 textno=ER_LOCK_WAIT_TIMEOUT; 01073 break; 01074 case HA_ERR_READ_ONLY_TRANSACTION: 01075 textno=ER_READ_ONLY_TRANSACTION; 01076 break; 01077 case HA_ERR_LOCK_DEADLOCK: 01078 textno=ER_LOCK_DEADLOCK; 01079 break; 01080 case HA_ERR_WRONG_COMMAND: 01081 textno=ER_ILLEGAL_HA; 01082 break; 01083 default: 01084 textno=ER_CANT_LOCK; 01085 break; 01086 } 01087 01088 if ( textno == ER_ILLEGAL_HA ) 01089 my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table); 01090 else 01091 my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error); 01092 01093 DBUG_VOID_RETURN; 01094 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void reset_lock_data | ( | MYSQL_LOCK * | sql_lock | ) | [static] |
Definition at line 785 of file lock.cc.
References st_mysql_lock::lock_count, st_mysql_lock::locks, and TL_UNLOCK.
Referenced by mysql_lock_tables().
00786 { 00787 THR_LOCK_DATA **ldata; 00788 THR_LOCK_DATA **ldata_end; 00789 00790 for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count; 00791 ldata < ldata_end; 00792 ldata++) 00793 { 00794 /* Reset lock type. */ 00795 (*ldata)->type= TL_UNLOCK; 00796 } 00797 }
Here is the caller graph for this function:

| void start_waiting_global_read_lock | ( | THD * | thd | ) |
Definition at line 1304 of file lock.cc.
References COND_global_read_lock, DBUG_ENTER, DBUG_VOID_RETURN, LOCK_global_read_lock, pthread_mutex_lock, pthread_mutex_unlock, and unlikely.
Referenced by ha_commit_trans(), lock_and_wait_for_table_name(), mysql_alter_db(), mysql_create_db(), mysql_create_or_drop_trigger(), mysql_execute_command(), mysql_rename_tables(), mysql_rm_db(), and mysql_rm_table().
01305 { 01306 bool tmp; 01307 DBUG_ENTER("start_waiting_global_read_lock"); 01308 if (unlikely(thd->global_read_lock)) 01309 DBUG_VOID_RETURN; 01310 (void) pthread_mutex_lock(&LOCK_global_read_lock); 01311 tmp= (!--protect_against_global_read_lock && 01312 (waiting_for_read_lock || global_read_lock_blocks_commit)); 01313 (void) pthread_mutex_unlock(&LOCK_global_read_lock); 01314 if (tmp) 01315 pthread_cond_broadcast(&COND_global_read_lock); 01316 DBUG_VOID_RETURN; 01317 }
Here is the caller graph for this function:

Definition at line 630 of file lock.cc.
References DBUG_ENTER, DBUG_RETURN, error, F_UNLCK, and print_lock_error().
Referenced by mysql_unlock_tables().
00631 { 00632 int error,error_code; 00633 DBUG_ENTER("unlock_external"); 00634 00635 error_code=0; 00636 do 00637 { 00638 if ((*table)->current_lock != F_UNLCK) 00639 { 00640 (*table)->current_lock = F_UNLCK; 00641 if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK))) 00642 { 00643 error_code=error; 00644 print_lock_error(error_code, (*table)->file->table_type()); 00645 } 00646 } 00647 table++; 00648 } while (--count); 00649 DBUG_RETURN(error_code); 00650 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void unlock_global_read_lock | ( | THD * | thd | ) |
Definition at line 1219 of file lock.cc.
References COND_global_read_lock, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, LOCK_global_read_lock, MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT, pthread_mutex_lock, and pthread_mutex_unlock.
Referenced by mysql_execute_command(), and reload_acl_and_cache().
01220 { 01221 uint tmp; 01222 DBUG_ENTER("unlock_global_read_lock"); 01223 DBUG_PRINT("info", 01224 ("global_read_lock: %u global_read_lock_blocks_commit: %u", 01225 global_read_lock, global_read_lock_blocks_commit)); 01226 01227 pthread_mutex_lock(&LOCK_global_read_lock); 01228 tmp= --global_read_lock; 01229 if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT) 01230 --global_read_lock_blocks_commit; 01231 pthread_mutex_unlock(&LOCK_global_read_lock); 01232 /* Send the signal outside the mutex to avoid a context switch */ 01233 if (!tmp) 01234 { 01235 DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock")); 01236 pthread_cond_broadcast(&COND_global_read_lock); 01237 } 01238 thd->global_read_lock= 0; 01239 01240 DBUG_VOID_RETURN; 01241 }
Here is the caller graph for this function:

| void unlock_table_name | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 936 of file lock.cc.
References broadcast_refresh(), hash_delete(), open_cache, and st_table_list::table.
Referenced by LOGGER::deactivate_log_handler(), Log_to_csv_event_handler::flush(), lock_and_wait_for_table_name(), mysql_create_like_table(), mysql_create_or_drop_trigger(), mysql_truncate(), open_unireg_entry(), prepare_for_repair(), prepare_for_restore(), and unlock_table_names().
00937 { 00938 if (table_list->table) 00939 { 00940 hash_delete(&open_cache, (byte*) table_list->table); 00941 broadcast_refresh(); 00942 } 00943 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void unlock_table_names | ( | THD * | thd, | |
| TABLE_LIST * | table_list, | |||
| TABLE_LIST * | last_table | |||
| ) |
Definition at line 1052 of file lock.cc.
References broadcast_refresh(), DBUG_ENTER, DBUG_VOID_RETURN, and unlock_table_name().
Referenced by lock_table_names(), and mysql_rename_tables().
01054 { 01055 DBUG_ENTER("unlock_table_names"); 01056 for (TABLE_LIST *table= table_list; 01057 table != last_table; 01058 table= table->next_local) 01059 unlock_table_name(thd,table); 01060 broadcast_refresh(); 01061 DBUG_VOID_RETURN; 01062 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool wait_for_locked_table_names | ( | THD * | thd, | |
| TABLE_LIST * | table_list | |||
| ) |
Definition at line 966 of file lock.cc.
References COND_refresh, DBUG_ENTER, DBUG_RETURN, LOCK_open, locked_named_table(), pthread_mutex_lock, safe_mutex_assert_owner, and wait_for_condition().
Referenced by lock_and_wait_for_table_name(), lock_table_names(), open_unireg_entry(), and reopen_table().
00967 { 00968 bool result=0; 00969 DBUG_ENTER("wait_for_locked_table_names"); 00970 00971 safe_mutex_assert_owner(&LOCK_open); 00972 00973 while (locked_named_table(thd,table_list)) 00974 { 00975 if (thd->killed) 00976 { 00977 result=1; 00978 break; 00979 } 00980 wait_for_condition(thd, &LOCK_open, &COND_refresh); 00981 pthread_mutex_lock(&LOCK_open); 00982 } 00983 DBUG_RETURN(result); 00984 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1247 of file lock.cc.
References COND_global_read_lock, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER, ER_CANT_UPDATE_WITH_READLOCK, LINT_INIT, LOCK_global_read_lock, LOCK_open, must_wait, my_message(), MYF, pthread_mutex_lock, pthread_mutex_unlock, refresh_version, safe_mutex_assert_not_owner, and unlikely.
Referenced by ha_commit_trans(), lock_and_wait_for_table_name(), mysql_alter_db(), mysql_create_db(), mysql_create_or_drop_trigger(), mysql_execute_command(), mysql_lock_tables(), mysql_rename_tables(), mysql_rm_db(), and mysql_rm_table().
01249 { 01250 const char *old_message; 01251 bool result= 0, need_exit_cond; 01252 DBUG_ENTER("wait_if_global_read_lock"); 01253 01254 LINT_INIT(old_message); 01255 /* 01256 Assert that we do not own LOCK_open. If we would own it, other 01257 threads could not close their tables. This would make a pretty 01258 deadlock. 01259 */ 01260 safe_mutex_assert_not_owner(&LOCK_open); 01261 01262 (void) pthread_mutex_lock(&LOCK_global_read_lock); 01263 if ((need_exit_cond= must_wait)) 01264 { 01265 if (thd->global_read_lock) // This thread had the read locks 01266 { 01267 if (is_not_commit) 01268 my_message(ER_CANT_UPDATE_WITH_READLOCK, 01269 ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0)); 01270 (void) pthread_mutex_unlock(&LOCK_global_read_lock); 01271 /* 01272 We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does. 01273 This allowance is needed to not break existing versions of innobackup 01274 which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT. 01275 */ 01276 DBUG_RETURN(is_not_commit); 01277 } 01278 old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock, 01279 "Waiting for release of readlock"); 01280 while (must_wait && ! thd->killed && 01281 (!abort_on_refresh || thd->version == refresh_version)) 01282 { 01283 DBUG_PRINT("signal", ("Waiting for COND_global_read_lock")); 01284 (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock); 01285 DBUG_PRINT("signal", ("Got COND_global_read_lock")); 01286 } 01287 if (thd->killed) 01288 result=1; 01289 } 01290 if (!abort_on_refresh && !result) 01291 protect_against_global_read_lock++; 01292 /* 01293 The following is only true in case of a global read locks (which is rare) 01294 and if old_message is set 01295 */ 01296 if (unlikely(need_exit_cond)) 01297 thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock 01298 else 01299 pthread_mutex_unlock(&LOCK_global_read_lock); 01300 DBUG_RETURN(result); 01301 }
Here is the call graph for this function:

Here is the caller graph for this function:

| volatile uint global_read_lock = 0 |
| volatile uint global_read_lock_blocks_commit = 0 |
Definition at line 33 of file sql_base.cc.
Referenced by cached_open_tables(), close_cached_tables(), close_thread_table(), close_thread_tables(), create_table_from_items(), display_table_locks(), drop_locked_tables(), flush_tables(), list_open_tables(), lock_table_name(), mysql_wait_completed_table(), open_table(), print_cached_tables(), remove_db_from_cache(), remove_table_from_cache(), reopen_tables(), table_cache_free(), table_cache_init(), table_is_used(), unlink_open_table(), unlock_table_name(), and update_frm_version().
volatile uint protect_against_global_read_lock = 0 [static] |
int thr_lock_errno_to_mysql[] [static] |
Initial value:
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK }
Definition at line 111 of file lock.cc.
Referenced by mysql_lock_tables().
volatile uint waiting_for_read_lock = 0 [static] |
1.4.7

