MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
thread_test.c
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include <my_global.h>
17 
18 #include <my_sys.h>
19 #include <my_pthread.h>
20 #include "mysql.h"
21 #include <my_getopt.h>
22 
23 static my_bool version, verbose, tty_password= 0;
24 static uint thread_count,number_of_tests=1000,number_of_threads=2;
25 static pthread_cond_t COND_thread_count;
26 static pthread_mutex_t LOCK_thread_count;
27 
28 static char *database,*host,*user,*password,*unix_socket,*query;
29 uint tcp_port;
30 
31 #ifndef __WIN__
32 void *test_thread(void *arg __attribute__((unused)))
33 #else
34 unsigned __stdcall test_thread(void *arg __attribute__((unused)))
35 #endif
36 {
37  MYSQL *mysql;
38  uint count;
39 
40  mysql=mysql_init(NULL);
41  if (!mysql_real_connect(mysql,host,user,password,database,tcp_port,
42  unix_socket,0))
43  {
44  fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(mysql));
45  perror("");
46  goto end;
47  }
48  mysql.reconnect= 1;
49  if (verbose) { putchar('*'); fflush(stdout); }
50  for (count=0 ; count < number_of_tests ; count++)
51  {
52  MYSQL_RES *res;
53  if (mysql_query(mysql,query))
54  {
55  fprintf(stderr,"Query failed (%s)\n",mysql_error(mysql));
56  goto end;
57  }
58  if (!(res=mysql_store_result(mysql)))
59  {
60  fprintf(stderr,"Couldn't get result from %s\n", mysql_error(mysql));
61  goto end;
62  }
63  mysql_free_result(res);
64  if (verbose) { putchar('.'); fflush(stdout); }
65  }
66 end:
67  if (verbose) { putchar('#'); fflush(stdout); }
68  mysql_close(mysql);
69  pthread_mutex_lock(&LOCK_thread_count);
70  thread_count--;
71  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
72  pthread_mutex_unlock(&LOCK_thread_count);
73  pthread_exit(0);
74  return 0;
75 }
76 
77 
78 static struct my_option my_long_options[] =
79 {
80  {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
81  0, 0, 0, 0, 0},
82  {"database", 'D', "Database to use", &database, &database,
83  0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
84  {"host", 'h', "Connect to host", &host, &host, 0, GET_STR,
85  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
86  {"password", 'p',
87  "Password to use when connecting to server. If password is not given it's asked from the tty.",
88  0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
89  {"user", 'u', "User for login if not current user", &user,
90  &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
91  {"version", 'V', "Output version information and exit",
92  0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
93  {"verbose", 'v', "Write some progress indicators", &verbose,
94  &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
95  {"query", 'Q', "Query to execute in each threads", &query,
96  &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
97  {"port", 'P', "Port number to use for connection or 0 for default to, in "
98  "order of preference, my.cnf, $MYSQL_TCP_PORT, "
99 #if MYSQL_PORT_DEFAULT == 0
100  "/etc/services, "
101 #endif
102  "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
103  &tcp_port,
104  &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
105  {"socket", 'S', "Socket file to use for connection", &unix_socket,
106  &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
107  {"test-count", 'c', "Run test count times (default %d)",
108  &number_of_tests, &number_of_tests, 0, GET_UINT,
109  REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
110  {"thread-count", 't', "Number of threads to start",
111  &number_of_threads, &number_of_threads, 0, GET_UINT,
112  REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
113  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
114 };
115 
116 
117 static const char *load_default_groups[]= { "client",0 };
118 
119 static void usage()
120 {
121  printf("Connection to a mysql server with multiple threads\n");
122  if (version)
123  return;
124  puts("This software comes with ABSOLUTELY NO WARRANTY.\n");
125  printf("Usage: %s [OPTIONS] [database]\n", my_progname);
126 
127  my_print_help(my_long_options);
128  print_defaults("my",load_default_groups);
129  my_print_variables(my_long_options);
130  printf("\nExample usage:\n\n\
131 %s -Q 'select * from mysql.user' -c %d -t %d\n",
132  my_progname, number_of_tests, number_of_threads);
133 }
134 
135 
136 static my_bool
137 get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
138  char *argument)
139 {
140  switch (optid) {
141  case 'p':
142  if (argument)
143  {
144  my_free(password);
145  password= my_strdup(argument, MYF(MY_FAE));
146  while (*argument) *argument++= 'x'; /* Destroy argument */
147  }
148  else
149  tty_password= 1;
150  break;
151  case 'V':
152  version= 1;
153  usage();
154  exit(0);
155  break;
156  case '?':
157  case 'I': /* Info */
158  usage();
159  exit(1);
160  break;
161  }
162  return 0;
163 }
164 
165 
166 static void get_options(int argc, char **argv)
167 {
168  int ho_error;
169 
170  if ((ho_error= load_defaults("my",load_default_groups,&argc,&argv)) ||
171  (ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
172  exit(ho_error);
173 
174  free_defaults(argv);
175  if (tty_password)
176  password=get_tty_password(NullS);
177  return;
178 }
179 
180 
181 int main(int argc, char **argv)
182 {
183  pthread_t tid;
184  pthread_attr_t thr_attr;
185  uint i;
186  int error;
187  MY_INIT(argv[0]);
188  get_options(argc,argv);
189 
190  if ((error=pthread_cond_init(&COND_thread_count,NULL)))
191  {
192  fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
193  error,errno);
194  exit(1);
195  }
196  pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
197 
198  if ((error=pthread_attr_init(&thr_attr)))
199  {
200  fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
201  error,errno);
202  exit(1);
203  }
204  if ((error=pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED)))
205  {
206  fprintf(stderr,
207  "Got error: %d from pthread_attr_setdetachstate (errno: %d)",
208  error,errno);
209  exit(1);
210  }
211 
212  printf("Init ok. Creating %d threads\n",number_of_threads);
213  for (i=1 ; i <= number_of_threads ; i++)
214  {
215  int *param= &i;
216 
217  if (verbose) { putchar('+'); fflush(stdout); }
218  pthread_mutex_lock(&LOCK_thread_count);
219  if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
220  {
221  fprintf(stderr,"\nGot error: %d from pthread_create (errno: %d) when creating thread: %i\n",
222  error,errno,i);
223  pthread_mutex_unlock(&LOCK_thread_count);
224  exit(1);
225  }
226  thread_count++;
227  pthread_mutex_unlock(&LOCK_thread_count);
228  }
229 
230  printf("Waiting for threads to finnish\n");
231  error=pthread_mutex_lock(&LOCK_thread_count);
232  while (thread_count)
233  {
234  if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
235  fprintf(stderr,"\nGot error: %d from pthread_cond_wait\n",error);
236  }
237  pthread_mutex_unlock(&LOCK_thread_count);
238  pthread_attr_destroy(&thr_attr);
239  printf("\nend\n");
240 
241  my_end(0);
242  return 0;
243 
244  exit(0);
245  return 0; /* Keep some compilers happy */
246 }
247