deadlock_test.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <mysql.h>
  14. #include <stdio.h>
  15. #include <stdarg.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. typedef unsigned char uchar;
  20. static void die(char* fmt, ...);
  21. static void safe_query(MYSQL* mysql, char* query, int read_ok);
  22. static void run_query_batch(int* order, int num_queries);
  23. static void permute(int *order, int num_queries);
  24. static void permute_aux(int *order, int num_queries, int* fixed);
  25. static void dump_result(MYSQL* mysql, char* query);
  26. int count = 0;
  27. struct query
  28. {
  29.   MYSQL* mysql;
  30.   char* query;
  31.   int read_ok;
  32.   int pri;
  33.   int dump_result;
  34. };
  35. MYSQL lock, sel, del_ins;
  36. struct query queries[] =
  37. {
  38.   {&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
  39.   {&del_ins, "insert delayed into foo values(1)", 1, 0, 0},
  40.   {&lock, "lock tables foo write", 1, 1, 0},
  41.   {&lock, "unlock tables", 1,2, 0},
  42.   {&sel, "select * from foo", 0,0, 0},
  43.   {&del_ins, "insert  into foo values(4)", 0,3, 0},
  44.   {0,0,0}
  45. };
  46. static void die(char* fmt, ...)
  47. {
  48.   va_list args;
  49.   va_start(args, fmt);
  50.   fprintf(stderr, "ERROR: ");
  51.   vfprintf(stderr, fmt, args);
  52.   fprintf(stderr, "n");
  53.   va_end(args);
  54.   exit(1);
  55. }
  56. static void permute(int *order, int num_queries)
  57. {
  58.   int *fixed;
  59.   if(num_queries < 2) return;
  60.   if(!(fixed = (int*)malloc(num_queries * sizeof(int))))
  61.     die("malloc() failed");
  62.   memset(fixed, 0, num_queries * sizeof(int));
  63.   permute_aux(order, num_queries, fixed);
  64.   free(fixed);
  65. }
  66. static order_ok(int *order, int num_queries)
  67. {
  68.   int i,j, pri_i, pri_j;
  69.   for(i = 0; i < num_queries; i++)
  70.     {
  71.       if((pri_i = queries[order[i]].pri))
  72. for(j = i + 1; j < num_queries; j++)
  73.   {
  74.     pri_j = queries[order[j]].pri;
  75.     if(pri_j && pri_i > pri_j)
  76.       return 0;
  77.   }
  78.     }
  79.   return 1;
  80. }
  81. static void permute_aux(int *order, int num_queries, int* fixed)
  82. {
  83.   int *p,*p1,j,i,tmp, num_free = 0;
  84.   p = fixed;
  85.   for(i = 0; i < num_queries; i++, p++)
  86.     {
  87.       if(!*p)
  88. {
  89.   num_free++;
  90.   *p = 1;
  91.   for(j = 0, p1 = fixed ;
  92.       j < num_queries; j++,p1++)
  93.     {
  94.       if(!*p1)
  95. {
  96.   tmp = order[i];
  97.   order[i] = order[j];
  98.   order[j] = tmp;
  99.   *p1 = 1;
  100.   permute_aux(order, num_queries, fixed);
  101.   tmp = order[i];
  102.   order[i] = order[j];
  103.   order[j] = tmp;
  104.   *p1 = 0;
  105. }
  106.     }
  107.   *p = 0;
  108. }
  109.     }
  110.   /*printf("num_free = %dn", num_free); */
  111.   if(num_free <= 1)
  112.     {
  113.       count++;
  114.       if(order_ok(order, num_queries))
  115.         run_query_batch(order, num_queries);
  116.     }
  117. }
  118. static void run_query_batch(int* order, int num_queries)
  119. {
  120.   int i;
  121.   struct query* q;
  122.   int *save_order;
  123.   safe_query(&lock, "delete from foo", 1);
  124.   save_order = order;
  125.   for(i = 0; i < num_queries; i++,order++)
  126.     {
  127.       q = queries + *order;
  128.       printf("query='%s'n", q->query);
  129.       safe_query(q->mysql, q->query, q->read_ok);
  130.     }
  131.   order = save_order;
  132.   for(i = 0; i < num_queries; i++,order++)
  133.     {
  134.       q = queries + *order;
  135.       if(q->dump_result)
  136.        dump_result(q->mysql, q->query);
  137.     }
  138.   printf("n");
  139. }
  140. static void safe_net_read(NET* net, char* query)
  141. {
  142.   int len;
  143.   len = my_net_read(net); 
  144.   if(len == packet_error || !len)
  145.     die("Error running query '%s'", query);
  146.   if(net->read_pos[0] == 255)
  147.     die("Error running query '%s'", query);
  148. }
  149. static void safe_query(MYSQL* mysql, char* query, int read_ok)
  150. {
  151.   int len;
  152.   NET* net = &mysql->net;
  153.   net_clear(net);
  154.   if(net_write_command(net,(uchar)COM_QUERY, query,strlen(query)))
  155.     die("Error running query '%s': %s", query, mysql_error(mysql));
  156.   if(read_ok)
  157.     {
  158.       safe_net_read(net, query);
  159.     }
  160. }
  161. static void dump_result(MYSQL* mysql, char* query)
  162. {
  163.   MYSQL_RES* res;
  164.   safe_net_read(&mysql->net, query);
  165.   res = mysql_store_result(mysql);
  166.   if(res)
  167.    mysql_free_result(res);
  168. }
  169. static int* init_order(int* num_queries)
  170. {
  171.   struct query* q;
  172.   int *order, *order_end, *p;
  173.   int n,i;
  174.   for(q = queries; q->mysql; q++)
  175.     ;
  176.   n = q - queries;
  177.   if(!(order = (int*) malloc(n * sizeof(int))))
  178.     die("malloc() failed");
  179.   order_end = order + n;
  180.   for(p = order,i = 0; p < order_end; p++,i++)
  181.     *p = i;
  182.   *num_queries = n;
  183.   return order;
  184. }
  185. int main()
  186. {
  187.   char* user = "root", *pass = "", *host = "localhost", *db = "test";
  188.   int *order, num_queries;
  189.   order = init_order(&num_queries);
  190.   if(!mysql_init(&lock) || !mysql_init(&sel) || !mysql_init(&del_ins))
  191.     die("error in mysql_init()");
  192.   mysql_options(&lock, MYSQL_READ_DEFAULT_GROUP, "mysql");
  193.   mysql_options(&sel, MYSQL_READ_DEFAULT_GROUP, "mysql");
  194.   mysql_options(&del_ins, MYSQL_READ_DEFAULT_GROUP, "mysql");
  195.   if(!mysql_real_connect(&lock, host, user, pass, db, 0,0,0 ) ||
  196.      !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) ||
  197.      !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 ))
  198.     die("Error in mysql_real_connect(): %s", mysql_error(&lock));
  199.   permute(order, num_queries);
  200.   printf("count = %dn", count);
  201.   mysql_close(&lock);
  202.   mysql_close(&sel);
  203.   mysql_close(&del_ins);
  204.   free(order);
  205. }