summaryrefslogtreecommitdiffstats
path: root/tests/thread_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/thread_test.c')
-rw-r--r--tests/thread_test.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/tests/thread_test.c b/tests/thread_test.c
new file mode 100644
index 00000000..8242811c
--- /dev/null
+++ b/tests/thread_test.c
@@ -0,0 +1,248 @@
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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; version 2 of the License.
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <my_global.h>
+
+#include <my_sys.h>
+#include <my_pthread.h>
+#include "mysql.h"
+#include <my_getopt.h>
+
+static my_bool version, verbose, tty_password= 0;
+static uint thread_count,number_of_tests=1000,number_of_threads=2;
+static pthread_cond_t COND_thread_count;
+static pthread_mutex_t LOCK_thread_count;
+
+static char *database,*host,*user,*password,*unix_socket,*query;
+uint tcp_port;
+
+#ifndef _WIN32
+void *test_thread(void *arg __attribute__((unused)))
+#else
+unsigned __stdcall test_thread(void *arg __attribute__((unused)))
+#endif
+{
+ MYSQL *mysql;
+ uint count;
+
+ mysql=mysql_init(NULL);
+ if (!mysql_real_connect(mysql,host,user,password,database,tcp_port,
+ unix_socket,0))
+ {
+ fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(mysql));
+ perror("");
+ goto end;
+ }
+ mysql.reconnect= 1;
+ if (verbose) { putchar('*'); fflush(stdout); }
+ for (count=0 ; count < number_of_tests ; count++)
+ {
+ MYSQL_RES *res;
+ if (mysql_query(mysql,query))
+ {
+ fprintf(stderr,"Query failed (%s)\n",mysql_error(mysql));
+ goto end;
+ }
+ if (!(res=mysql_store_result(mysql)))
+ {
+ fprintf(stderr,"Couldn't get result from %s\n", mysql_error(mysql));
+ goto end;
+ }
+ mysql_free_result(res);
+ if (verbose) { putchar('.'); fflush(stdout); }
+ }
+end:
+ if (verbose) { putchar('#'); fflush(stdout); }
+ mysql_close(mysql);
+ pthread_mutex_lock(&LOCK_thread_count);
+ thread_count--;
+ pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_exit(0);
+ return 0;
+}
+
+
+static struct my_option my_long_options[] =
+{
+ {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+ 0, 0, 0, 0, 0},
+ {"database", 'D', "Database to use", &database, &database,
+ 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"host", 'h', "Connect to host", &host, &host, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"password", 'p',
+ "Password to use when connecting to server. If password is not given it's asked from the tty.",
+ 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"user", 'u', "User for login if not current user", &user,
+ &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"version", 'V', "Output version information and exit",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"verbose", 'v', "Write some progress indicators", &verbose,
+ &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"query", 'Q', "Query to execute in each threads", &query,
+ &query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"port", 'P', "Port number to use for connection or 0 for default to, in "
+ "order of preference, my.cnf, $MYSQL_TCP_PORT, "
+#if MYSQL_PORT_DEFAULT == 0
+ "/etc/services, "
+#endif
+ "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
+ &tcp_port,
+ &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0},
+ {"socket", 'S', "Socket file to use for connection", &unix_socket,
+ &unix_socket, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-count", 'c', "Run test count times (default %d)",
+ &number_of_tests, &number_of_tests, 0, GET_UINT,
+ REQUIRED_ARG, 1000, 0, 0, 0, 0, 0},
+ {"thread-count", 't', "Number of threads to start",
+ &number_of_threads, &number_of_threads, 0, GET_UINT,
+ REQUIRED_ARG, 2, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+static const char *load_default_groups[]=
+{ "client", "client-server", "client-mariadb", 0 };
+
+static void usage()
+{
+ printf("Connection to a mysql server with multiple threads\n");
+ if (version)
+ return;
+ puts("This software comes with ABSOLUTELY NO WARRANTY.\n");
+ printf("Usage: %s [OPTIONS] [database]\n", my_progname);
+
+ my_print_help(my_long_options);
+ print_defaults("my",load_default_groups);
+ my_print_variables(my_long_options);
+ printf("\nExample usage:\n\n\
+%s -Q 'select * from mysql.user' -c %d -t %d\n",
+ my_progname, number_of_tests, number_of_threads);
+}
+
+
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ char *argument)
+{
+ switch (optid) {
+ case 'p':
+ if (argument)
+ {
+ my_free(password);
+ password= my_strdup(argument, MYF(MY_FAE));
+ while (*argument) *argument++= 'x'; /* Destroy argument */
+ }
+ else
+ tty_password= 1;
+ break;
+ case 'V':
+ version= 1;
+ usage();
+ exit(0);
+ break;
+ case '?':
+ case 'I': /* Info */
+ usage();
+ exit(1);
+ break;
+ }
+ return 0;
+}
+
+
+static void get_options(int argc, char **argv)
+{
+ int ho_error;
+
+ load_defaults_or_exit("my", load_default_groups, &argc, &argv);
+ if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
+ exit(ho_error);
+
+ free_defaults(argv);
+ if (tty_password)
+ password=my_get_tty_password(NullS);
+ return;
+}
+
+
+int main(int argc, char **argv)
+{
+ pthread_t tid;
+ pthread_attr_t thr_attr;
+ uint i;
+ int error;
+ MY_INIT(argv[0]);
+ get_options(argc,argv);
+
+ if ((error=pthread_cond_init(&COND_thread_count,NULL)))
+ {
+ fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+ pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
+
+ if ((error=pthread_attr_init(&thr_attr)))
+ {
+ fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+ if ((error=pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED)))
+ {
+ fprintf(stderr,
+ "Got error: %d from pthread_attr_setdetachstate (errno: %d)",
+ error,errno);
+ exit(1);
+ }
+
+ printf("Init ok. Creating %d threads\n",number_of_threads);
+ for (i=1 ; i <= number_of_threads ; i++)
+ {
+ int *param= &i;
+
+ if (verbose) { putchar('+'); fflush(stdout); }
+ pthread_mutex_lock(&LOCK_thread_count);
+ if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
+ {
+ fprintf(stderr,"\nGot error: %d from pthread_create (errno: %d) when creating thread: %i\n",
+ error,errno,i);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ exit(1);
+ }
+ thread_count++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+ }
+
+ printf("Waiting for threads to finnish\n");
+ error=pthread_mutex_lock(&LOCK_thread_count);
+ while (thread_count)
+ {
+ if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
+ fprintf(stderr,"\nGot error: %d from pthread_cond_wait\n",error);
+ }
+ pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_attr_destroy(&thr_attr);
+ printf("\nend\n");
+
+ my_end(0);
+ return 0;
+
+ exit(0);
+ return 0; /* Keep some compilers happy */
+}
+