mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
283 lines
7.5 KiB
C
283 lines
7.5 KiB
C
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library 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
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
MA 02111-1307, USA */
|
|
|
|
#include <global.h>
|
|
#include <my_sys.h>
|
|
#include <my_pthread.h>
|
|
#include "mysql.h"
|
|
#include <getopt.h>
|
|
|
|
#ifndef THREAD
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
printf("This test must be compiled with multithread support to work\n");
|
|
exit(1);
|
|
}
|
|
#else
|
|
|
|
static my_bool version,verbose;
|
|
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 __WIN__
|
|
void *test_thread(void *arg)
|
|
#else
|
|
unsigned __stdcall test_thread(void *arg)
|
|
#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;
|
|
}
|
|
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--;
|
|
VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
|
|
pthread_mutex_unlock(&LOCK_thread_count);
|
|
pthread_exit(0);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static struct option long_options[] =
|
|
{
|
|
{"help", no_argument, 0, '?'},
|
|
{"database", required_argument, 0, 'D'},
|
|
{"host", required_argument, 0, 'h'},
|
|
{"password", optional_argument, 0, 'p'},
|
|
{"user", required_argument, 0, 'u'},
|
|
{"version", no_argument, 0, 'V'},
|
|
{"verbose", no_argument, 0, 'v'},
|
|
{"query", required_argument, 0, 'Q'},
|
|
{"port", required_argument, 0, 'P'},
|
|
{"socket", required_argument, 0, 'S'},
|
|
{"test-count",required_argument, 0, 'c'},
|
|
{"thread-count",required_argument, 0, 't'},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
static const char *load_default_groups[]= { "client",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);
|
|
printf("\n\
|
|
-?, --help Display this help and exit\n\
|
|
-c #, --test-count=# Run test count times (default %d)\n",number_of_tests);
|
|
printf("\
|
|
-D, --database=.. Database to use\n\
|
|
-h, --host=... Connect to host\n\
|
|
-p[password], --password[=...]\n\
|
|
Password to use when connecting to server\n\
|
|
If password is not given it's asked from the tty.\n");
|
|
printf("\n\
|
|
-P --port=... Port number to use for connection\n\
|
|
-Q, --query=... Query to execute in each threads\n\
|
|
-S --socket=... Socket file to use for connection\n");
|
|
printf("\
|
|
-t --thread-count=# Number of threads to start (default: %d) \n\
|
|
-u, --user=# User for login if not current user\n\
|
|
-v, --verbose Write some progress indicators\n\
|
|
-V, --version Output version information and exit\n",
|
|
number_of_threads);
|
|
|
|
print_defaults("my",load_default_groups);
|
|
|
|
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 void get_options(int argc, char **argv)
|
|
{
|
|
int c,option_index=0,error=0;
|
|
bool tty_password=0;
|
|
load_defaults("my",load_default_groups,&argc,&argv);
|
|
|
|
while ((c=getopt_long(argc,argv, "c:D:h:p::VQ:P:S:t:?I",
|
|
long_options, &option_index)) != EOF)
|
|
{
|
|
switch (c) {
|
|
case 'c':
|
|
number_of_tests=atoi(optarg);
|
|
break;
|
|
case 'D':
|
|
my_free(database,MYF(MY_ALLOW_ZERO_PTR));
|
|
database=my_strdup(optarg,MYF(MY_WME));
|
|
break;
|
|
case 'h':
|
|
host = optarg;
|
|
break;
|
|
case 'Q': /* Allow old 'q' option */
|
|
query= optarg;
|
|
break;
|
|
case 'p':
|
|
if (optarg)
|
|
{
|
|
my_free(password,MYF(MY_ALLOW_ZERO_PTR));
|
|
password=my_strdup(optarg,MYF(MY_FAE));
|
|
while (*optarg) *optarg++= 'x'; /* Destroy argument */
|
|
}
|
|
else
|
|
tty_password=1;
|
|
break;
|
|
case 'u':
|
|
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
|
|
user= my_strdup(optarg,MYF(0));
|
|
break;
|
|
case 'P':
|
|
tcp_port= (unsigned int) atoi(optarg);
|
|
break;
|
|
case 'S':
|
|
my_free(unix_socket,MYF(MY_ALLOW_ZERO_PTR));
|
|
unix_socket= my_strdup(optarg,MYF(0));
|
|
break;
|
|
case 't':
|
|
number_of_threads=atoi(optarg);
|
|
break;
|
|
case 'v':
|
|
verbose=1;
|
|
break;
|
|
case 'V':
|
|
version=1;
|
|
usage();
|
|
exit(0);
|
|
break;
|
|
default:
|
|
fprintf(stderr,"Illegal option character '%c'\n",opterr);
|
|
/* Fall through */
|
|
case '?':
|
|
case 'I': /* Info */
|
|
error++;
|
|
break;
|
|
}
|
|
}
|
|
if (error || argc != optind)
|
|
{
|
|
usage();
|
|
exit(1);
|
|
}
|
|
free_defaults(argv);
|
|
if (tty_password)
|
|
password=get_tty_password(NullS);
|
|
return;
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
pthread_t tid;
|
|
pthread_attr_t thr_attr;
|
|
int i,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,NULL);
|
|
|
|
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 */
|
|
}
|
|
|
|
#endif /* THREAD */
|