summaryrefslogtreecommitdiff
path: root/div
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2000-11-29 05:10:03 +0200
committerunknown <monty@donna.mysql.com>2000-11-29 05:10:03 +0200
commit98501adef90d44b258b98e0d229ac37ba85e70ee (patch)
treeffad7ff555a4c4eec745a91a47593aa66b783028 /div
parent2c036ff7b95fd7350d9cb207470ae0022b81e76f (diff)
downloadmariadb-git-98501adef90d44b258b98e0d229ac37ba85e70ee.tar.gz
New vio file
Diffstat (limited to 'div')
-rw-r--r--div/deadlock_test.c238
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);
+}