#include <mysql.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <stdlib.h>Include dependency graph for deadlock_test.c:

Go to the source code of this file.
Classes | |
| struct | query |
Typedefs | |
| typedef unsigned char | uchar |
Functions | |
| static void | die (char *fmt,...) |
| static void | safe_query (MYSQL *mysql, char *query, int read_ok) |
| static void | run_query_batch (int *order, int num_queries) |
| static void | permute (int *order, int num_queries) |
| static void | permute_aux (int *order, int num_queries, int *fixed) |
| static void | dump_result (MYSQL *mysql, char *query) |
| static | order_ok (int *order, int num_queries) |
| static void | safe_net_read (NET *net, char *query) |
| static int * | init_order (int *num_queries) |
| int | main () |
Variables | |
| int | count = 0 |
| MYSQL | lock |
| MYSQL | sel |
| MYSQL | del_ins |
| query | queries [] |
| typedef unsigned char uchar |
Definition at line 24 of file deadlock_test.c.
| static void die | ( | char * | fmt, | |
| ... | ||||
| ) | [static] |
| static void dump_result | ( | MYSQL * | mysql, | |
| char * | query | |||
| ) | [static] |
Definition at line 186 of file deadlock_test.c.
References mysql, mysql_free_result(), mysql_store_result(), st_mysql::net, and safe_net_read().
Referenced by run_query_batch().
00187 { 00188 MYSQL_RES* res; 00189 safe_net_read(&mysql->net, query); 00190 res = mysql_store_result(mysql); 00191 if(res) 00192 mysql_free_result(res); 00193 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int* init_order | ( | int * | num_queries | ) | [static] |
Definition at line 195 of file deadlock_test.c.
References die(), malloc, query::mysql, n, order, p, and queries.
Referenced by main().
00196 { 00197 struct query* q; 00198 int *order, *order_end, *p; 00199 int n,i; 00200 00201 for(q = queries; q->mysql; q++) 00202 ; 00203 00204 n = q - queries; 00205 if(!(order = (int*) malloc(n * sizeof(int)))) 00206 die("malloc() failed"); 00207 order_end = order + n; 00208 for(p = order,i = 0; p < order_end; p++,i++) 00209 *p = i; 00210 *num_queries = n; 00211 return order; 00212 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int main | ( | void | ) |
Definition at line 214 of file deadlock_test.c.
References count, db, del_ins, die(), free, host, init_order(), lock, mysql_close(), mysql_error(), mysql_init(), mysql_options(), MYSQL_READ_DEFAULT_GROUP, mysql_real_connect(), order, pass, permute(), st_mysql::reconnect, sel, and user.
00215 { 00216 char* user = "root", *pass = "", *host = "localhost", *db = "test"; 00217 int *order, num_queries; 00218 order = init_order(&num_queries); 00219 if(!mysql_init(&lock) || !mysql_init(&sel) || !mysql_init(&del_ins)) 00220 die("error in mysql_init()"); 00221 00222 mysql_options(&lock, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00223 mysql_options(&sel, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00224 mysql_options(&del_ins, MYSQL_READ_DEFAULT_GROUP, "mysql"); 00225 00226 if(!mysql_real_connect(&lock, host, user, pass, db, 0,0,0 ) || 00227 !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) || 00228 !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 )) 00229 die("Error in mysql_real_connect(): %s", mysql_error(&lock)); 00230 lock.reconnect= sel.reconnect= del_ins.reconnect= 1; 00231 00232 permute(order, num_queries); 00233 printf("count = %d\n", count); 00234 00235 mysql_close(&lock); 00236 mysql_close(&sel); 00237 mysql_close(&del_ins); 00238 free(order); 00239 }
Here is the call graph for this function:

| static order_ok | ( | int * | order, | |
| int | num_queries | |||
| ) | [static] |
Definition at line 81 of file deadlock_test.c.
References query::pri, and queries.
Referenced by permute_aux().
00082 { 00083 int i,j, pri_i, pri_j; 00084 for(i = 0; i < num_queries; i++) 00085 { 00086 if((pri_i = queries[order[i]].pri)) 00087 for(j = i + 1; j < num_queries; j++) 00088 { 00089 pri_j = queries[order[j]].pri; 00090 if(pri_j && pri_i > pri_j) 00091 return 0; 00092 } 00093 } 00094 00095 return 1; 00096 }
Here is the caller graph for this function:

| static void permute | ( | int * | order, | |
| int | num_queries | |||
| ) | [static] |
Definition at line 68 of file deadlock_test.c.
References die(), free, malloc, memset, and permute_aux().
Referenced by main().
00069 { 00070 int *fixed; 00071 if(num_queries < 2) return; 00072 if(!(fixed = (int*)malloc(num_queries * sizeof(int)))) 00073 die("malloc() failed"); 00074 00075 memset(fixed, 0, num_queries * sizeof(int)); 00076 permute_aux(order, num_queries, fixed); 00077 00078 free(fixed); 00079 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void permute_aux | ( | int * | order, | |
| int | num_queries, | |||
| int * | fixed | |||
| ) | [static] |
Definition at line 98 of file deadlock_test.c.
References count, order_ok(), p, and run_query_batch().
Referenced by permute().
00099 { 00100 int *p,*p1,j,i,tmp, num_free = 0; 00101 p = fixed; 00102 for(i = 0; i < num_queries; i++, p++) 00103 { 00104 if(!*p) 00105 { 00106 num_free++; 00107 *p = 1; 00108 for(j = 0, p1 = fixed ; 00109 j < num_queries; j++,p1++) 00110 { 00111 if(!*p1) 00112 { 00113 tmp = order[i]; 00114 order[i] = order[j]; 00115 order[j] = tmp; 00116 *p1 = 1; 00117 permute_aux(order, num_queries, fixed); 00118 tmp = order[i]; 00119 order[i] = order[j]; 00120 order[j] = tmp; 00121 *p1 = 0; 00122 } 00123 } 00124 *p = 0; 00125 } 00126 } 00127 00128 /*printf("num_free = %d\n", num_free); */ 00129 00130 if(num_free <= 1) 00131 { 00132 count++; 00133 if(order_ok(order, num_queries)) 00134 run_query_batch(order, num_queries); 00135 } 00136 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void run_query_batch | ( | int * | order, | |
| int | num_queries | |||
| ) | [static] |
Definition at line 138 of file deadlock_test.c.
References dump_result(), query::dump_result, lock, query::mysql, queries, query::query, query::read_ok, and safe_query().
Referenced by permute_aux().
00139 { 00140 int i; 00141 struct query* q; 00142 int *save_order; 00143 safe_query(&lock, "delete from foo", 1); 00144 save_order = order; 00145 for(i = 0; i < num_queries; i++,order++) 00146 { 00147 q = queries + *order; 00148 printf("query='%s'\n", q->query); 00149 safe_query(q->mysql, q->query, q->read_ok); 00150 } 00151 order = save_order; 00152 for(i = 0; i < num_queries; i++,order++) 00153 { 00154 q = queries + *order; 00155 if(q->dump_result) 00156 dump_result(q->mysql, q->query); 00157 } 00158 printf("\n"); 00159 00160 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void safe_net_read | ( | NET * | net, | |
| char * | query | |||
| ) | [static] |
Definition at line 162 of file deadlock_test.c.
References die(), my_net_read(), packet_error, and st_net::read_pos.
Referenced by dump_result(), and safe_query().
00163 { 00164 int len; 00165 len = my_net_read(net); 00166 if(len == packet_error || !len) 00167 die("Error running query '%s'", query); 00168 if(net->read_pos[0] == 255) 00169 die("Error running query '%s'", query); 00170 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void safe_query | ( | MYSQL * | mysql, | |
| char * | query, | |||
| int | read_ok | |||
| ) | [static] |
Definition at line 173 of file deadlock_test.c.
References COM_QUERY, die(), mysql, mysql_error(), st_mysql::net, net_clear(), net_write_command(), safe_net_read(), and strlen().
Referenced by run_query_batch().
00174 { 00175 int len; 00176 NET* net = &mysql->net; 00177 net_clear(net); 00178 if(net_write_command(net,(uchar)COM_QUERY, query,strlen(query))) 00179 die("Error running query '%s': %s", query, mysql_error(mysql)); 00180 if(read_ok) 00181 { 00182 safe_net_read(net, query); 00183 } 00184 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int count = 0 |
Definition at line 32 of file deadlock_test.c.
Definition at line 44 of file deadlock_test.c.
Referenced by btr_search_update_block_hash_info(), clean_up_mutexes(), MutexVector< T >::clear(), create_table_from_items(), display_table_locks(), MutexVector< T >::erase(), Dbdict::execBACKUP_FRAGMENT_REQ(), handle_delayed_insert(), init_thread_environment(), lock_cancel_waiting_and_release(), lock_deadlock_occurs(), lock_deadlock_recursive(), lock_get_mode(), lock_get_n_rec_locks(), lock_get_src_table(), lock_get_type(), lock_get_wait(), lock_grant(), lock_is_table_exclusive(), lock_move_rec_list_end(), lock_move_rec_list_start(), lock_move_reorganize_page(), lock_number_of_rows_locked(), lock_print_info_all_transactions(), lock_rec_add_to_queue(), lock_rec_bitmap_reset(), lock_rec_cancel(), lock_rec_copy(), lock_rec_create(), lock_rec_dequeue_from_page(), lock_rec_enqueue_waiting(), lock_rec_find_set_bit(), lock_rec_find_similar_on_page(), lock_rec_free_all_from_discard_page(), lock_rec_get_first(), lock_rec_get_first_on_page(), lock_rec_get_first_on_page_addr(), lock_rec_get_gap(), lock_rec_get_insert_intention(), lock_rec_get_n_bits(), lock_rec_get_next(), lock_rec_get_next_on_page(), lock_rec_get_nth_bit(), lock_rec_get_prev(), lock_rec_get_rec_not_gap(), lock_rec_has_expl(), lock_rec_has_to_wait_in_queue(), lock_rec_inherit_to_gap(), lock_rec_inherit_to_gap_if_gap_lock(), lock_rec_insert_check_and_lock(), lock_rec_lock_fast(), lock_rec_move(), lock_rec_other_has_conflicting(), lock_rec_other_has_expl_req(), lock_rec_print(), lock_rec_queue_validate(), lock_rec_reset_and_release_wait(), lock_rec_reset_nth_bit(), lock_rec_set_nth_bit(), lock_rec_unlock(), lock_rec_validate_page(), lock_release_off_kernel(), lock_reset_all_on_table(), lock_reset_all_on_table_for_trx(), lock_reset_lock_and_trx_wait(), lock_set_lock_and_trx_wait(), lock_table_create(), lock_table_dequeue(), lock_table_enqueue_waiting(), lock_table_has(), lock_table_has_to_wait_in_queue(), lock_table_other_has_incompatible(), lock_table_print(), lock_table_queue_validate(), lock_table_remove_low(), lock_table_unlock(), lock_validate(), main(), mysql_ha_read(), mysql_unlock_read_tables(), MutexVector< T >::push_back(), reopen_tables(), run_query_batch(), rw_lock_create_func(), rw_lock_free(), rw_lock_is_locked(), rw_lock_s_lock_spin(), rw_lock_validate(), rw_lock_x_lock_func(), rw_lock_x_lock_low(), rw_lock_x_lock_move_ownership(), Dbtc::sendlqhkeyreq(), start_test(), sync_arr_cell_can_wake_up(), sync_thread_levels_g(), test_read(), test_rrnd(), test_update(), and test_write().
Initial value:
{
{&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
{&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
{&lock, "lock tables foo write", 1, 1, 0},
{&lock, "unlock tables", 1,2, 0},
{&sel, "select * from foo", 0,0, 0},
{&del_ins, "insert into foo values(4)", 0,3, 0},
{0,0,0}
}
Definition at line 46 of file deadlock_test.c.
Referenced by init_order(), order_ok(), run_query_batch(), run_task(), test_basic_cursors(), test_cursors_with_union(), and test_ps_null_param().
Definition at line 44 of file deadlock_test.c.
1.4.7

