diff options
author | unknown <monty@donna.mysql.com> | 2000-11-29 05:10:03 +0200 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2000-11-29 05:10:03 +0200 |
commit | 98501adef90d44b258b98e0d229ac37ba85e70ee (patch) | |
tree | ffad7ff555a4c4eec745a91a47593aa66b783028 /div | |
parent | 2c036ff7b95fd7350d9cb207470ae0022b81e76f (diff) | |
download | mariadb-git-98501adef90d44b258b98e0d229ac37ba85e70ee.tar.gz |
New vio file
Diffstat (limited to 'div')
-rw-r--r-- | div/deadlock_test.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/div/deadlock_test.c b/div/deadlock_test.c new file mode 100644 index 00000000000..a1cd97b7a78 --- /dev/null +++ b/div/deadlock_test.c @@ -0,0 +1,238 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <mysql.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +typedef unsigned char uchar; +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); + +int count = 0; + + +struct query +{ + MYSQL* mysql; + char* query; + int read_ok; + int pri; + int dump_result; +}; + +MYSQL lock, sel, del_ins; + +struct query queries[] = +{ + {&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} +}; + +static void die(char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + fprintf(stderr, "ERROR: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} + +static void permute(int *order, int num_queries) +{ + int *fixed; + if(num_queries < 2) return; + if(!(fixed = (int*)malloc(num_queries * sizeof(int)))) + die("malloc() failed"); + + memset(fixed, 0, num_queries * sizeof(int)); + permute_aux(order, num_queries, fixed); + + free(fixed); +} + +static order_ok(int *order, int num_queries) +{ + int i,j, pri_i, pri_j; + for(i = 0; i < num_queries; i++) + { + if((pri_i = queries[order[i]].pri)) + for(j = i + 1; j < num_queries; j++) + { + pri_j = queries[order[j]].pri; + if(pri_j && pri_i > pri_j) + return 0; + } + } + + return 1; +} + +static void permute_aux(int *order, int num_queries, int* fixed) +{ + int *p,*p1,j,i,tmp, num_free = 0; + p = fixed; + for(i = 0; i < num_queries; i++, p++) + { + if(!*p) + { + num_free++; + *p = 1; + for(j = 0, p1 = fixed ; + j < num_queries; j++,p1++) + { + if(!*p1) + { + tmp = order[i]; + order[i] = order[j]; + order[j] = tmp; + *p1 = 1; + permute_aux(order, num_queries, fixed); + tmp = order[i]; + order[i] = order[j]; + order[j] = tmp; + *p1 = 0; + } + } + *p = 0; + } + } + + //printf("num_free = %d\n", num_free); + + if(num_free <= 1) + { + count++; + if(order_ok(order, num_queries)) + run_query_batch(order, num_queries); + } +} + +static void run_query_batch(int* order, int num_queries) +{ + int i; + struct query* q; + int *save_order; + safe_query(&lock, "delete from foo", 1); + save_order = order; + for(i = 0; i < num_queries; i++,order++) + { + q = queries + *order; + printf("query='%s'\n", q->query); + safe_query(q->mysql, q->query, q->read_ok); + } + order = save_order; + for(i = 0; i < num_queries; i++,order++) + { + q = queries + *order; + if(q->dump_result) + dump_result(q->mysql, q->query); + } + printf("\n"); + +} + +static void safe_net_read(NET* net, char* query) +{ + int len; + len = my_net_read(net); + if(len == packet_error || !len) + die("Error running query '%s'", query); + if(net->read_pos[0] == 255) + die("Error running query '%s'", query); +} + + +static void safe_query(MYSQL* mysql, char* query, int read_ok) +{ + int len; + NET* net = &mysql->net; + net_clear(net); + if(net_write_command(net,(uchar)COM_QUERY, query,strlen(query))) + die("Error running query '%s': %s", query, mysql_error(mysql)); + if(read_ok) + { + safe_net_read(net, query); + } +} + +static void dump_result(MYSQL* mysql, char* query) +{ + MYSQL_RES* res; + safe_net_read(&mysql->net, query); + res = mysql_store_result(mysql); + if(res) + mysql_free_result(res); +} + +static int* init_order(int* num_queries) +{ + struct query* q; + int *order, *order_end, *p; + int n,i; + + for(q = queries; q->mysql; q++) + ; + + n = q - queries; + if(!(order = (int*) malloc(n * sizeof(int)))) + die("malloc() failed"); + order_end = order + n; + for(p = order,i = 0; p < order_end; p++,i++) + *p = i; + *num_queries = n; + return order; +} + +int main() +{ + char* user = "root", *pass = "", *host = "localhost", *db = "test"; + int *order, num_queries; + order = init_order(&num_queries); + if(!mysql_init(&lock) || !mysql_init(&sel) || !mysql_init(&del_ins)) + die("error in mysql_init()"); + + mysql_options(&lock, MYSQL_READ_DEFAULT_GROUP, "mysql"); + mysql_options(&sel, MYSQL_READ_DEFAULT_GROUP, "mysql"); + mysql_options(&del_ins, MYSQL_READ_DEFAULT_GROUP, "mysql"); + + if(!mysql_real_connect(&lock, host, user, pass, db, 0,0,0 ) || + !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) || + !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 )) + die("Error in mysql_real_connect(): %s", mysql_error(&lock)); + + permute(order, num_queries); + printf("count = %d\n", count); + + mysql_close(&lock); + mysql_close(&sel); + mysql_close(&del_ins); + free(order); +} |