Commit e91d1b2c authored by wax@mysql.com's avatar wax@mysql.com

Add shared memory protocol and option --protocol

parent fc54b137
......@@ -90,6 +90,7 @@ venu@myvenu.com
venu@work.mysql.com
vva@genie.(none)
walrus@mysql.com
wax@mysql.com
worm@altair.is.lan
zak@balfor.local
zak@linux.local
......
......@@ -37,4 +37,5 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL,
OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE,
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION };
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
OPT_SHARED_MEMORY_BASE_NAME };
......@@ -152,6 +152,11 @@ static FILE *PAGER, *OUTFILE;
static MEM_ROOT hash_mem_root;
static uint prompt_counter;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
#include "sslopt-vars.h"
#ifndef DBUG_OFF
......@@ -425,6 +430,9 @@ sig_handler mysql_end(int sig)
my_free(full_username,MYF(MY_ALLOW_ZERO_PTR));
my_free(part_username,MYF(MY_ALLOW_ZERO_PTR));
my_free(default_prompt,MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
my_free(current_prompt,MYF(MY_ALLOW_ZERO_PTR));
mysql_server_end();
free_defaults(defaults_argv);
......@@ -532,6 +540,8 @@ static struct my_option my_long_options[] =
{"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
(gptr*) &current_prompt, (gptr*) &current_prompt, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q',
"Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file. ",
(gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
......@@ -540,6 +550,11 @@ static struct my_option my_long_options[] =
0, 0, 0},
{"silent", 's', "Be more silent.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -644,6 +659,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case OPT_NOPAGER:
printf("WARNING: option deprecated; use --disable-pager instead.\n");
opt_nopager= 1;
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
break;
case 'A':
rehash= 0;
......@@ -706,7 +730,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
opt_mysql_unix_port= my_strdup(MYSQL_NAMEDPIPE, MYF(0));
opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
#include <sslopt-case.h>
......@@ -2349,6 +2373,12 @@ sql_real_connect(char *host,char *database,char *user,char *password,
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (safe_updates)
{
......
......@@ -23,6 +23,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
#include <sys/stat.h>
#include <mysql.h>
#define ADMIN_VERSION "8.38"
#define MAX_MYSQL_VAR 128
......@@ -42,6 +43,11 @@ static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations,
static ulong opt_connect_timeout, opt_shutdown_timeout;
static my_string unix_port=0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
/*
When using extended-status relatively, ex_val_max_len is the estimated
maximum length for any relative value printed by extended-status. The
......@@ -135,6 +141,8 @@ static struct my_option my_long_options[] =
#endif
{"port", 'P', "Port number to use for connection.", (gptr*) &tcp_port,
(gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"relative", 'r',
"Show difference between current and previous values when used with -i. Currently works only with extended-status.",
(gptr*) &opt_relative, (gptr*) &opt_relative, 0, GET_BOOL, NO_ARG, 0, 0, 0,
......@@ -142,6 +150,11 @@ static struct my_option my_long_options[] =
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"silent", 's', "Silently exit if one can't connect to server",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
......@@ -205,7 +218,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
unix_port=MYSQL_NAMEDPIPE;
opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case '#':
......@@ -234,6 +247,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
charsets_dir = argument;
#endif
break;
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
}
if (error)
{
......@@ -284,6 +306,12 @@ int main(int argc,char *argv[])
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (sql_connect(&mysql, option_wait))
error = 1;
else
......@@ -326,6 +354,9 @@ int main(int argc,char *argv[])
}
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
my_free(user,MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
free_defaults(save_argv);
my_end(0);
exit(error ? 1 : 0);
......
......@@ -41,6 +41,10 @@ static char *opt_password = 0, *current_user = 0, *default_charset = 0,
*current_host = 0;
static int first_error = 0;
DYNAMIC_ARRAY tables4repair;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
......@@ -109,6 +113,8 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q',
"If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.",
(gptr*) &opt_quick, (gptr*) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
......@@ -116,6 +122,11 @@ static struct my_option my_long_options[] =
{"repair", 'r',
"Can fix almost anything except unique keys that aren't unique.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"silent", 's', "Print only error messages.", (gptr*) &opt_silent,
(gptr*) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
......@@ -233,7 +244,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
opt_mysql_unix_port = MYSQL_NAMEDPIPE;
opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case '#':
......@@ -247,6 +258,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
verbose++;
break;
case 'V': print_version(); exit(0);
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
}
return 0;
}
......@@ -533,6 +553,12 @@ static int dbConnect(char *host, char *user, char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
......@@ -621,6 +647,9 @@ int main(int argc, char **argv)
if (opt_auto_repair)
delete_dynamic(&tables4repair);
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
my_end(0);
return(first_error!=0);
} /* main */
......@@ -90,6 +90,10 @@ extern ulong net_buffer_length;
static DYNAMIC_STRING extended_row;
#include <sslopt-vars.h>
FILE *md_result_file;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
static struct my_option my_long_options[] =
{
......@@ -200,6 +204,8 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
(gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"quote-names",'Q', "Quote table and column names with a `",
......@@ -208,6 +214,11 @@ static struct my_option my_long_options[] =
{"result-file", 'r',
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -338,7 +349,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
opt_mysql_unix_port=MYSQL_NAMEDPIPE;
opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case 'T':
......@@ -365,6 +376,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_TABLES:
opt_databases=0;
break;
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
}
return 0;
}
......@@ -473,6 +493,12 @@ static int dbConnect(char *host, char *user,char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port,
......@@ -1471,6 +1497,9 @@ int main(int argc, char **argv)
MYF(0), mysql_error(sock));
}
else if (opt_single_transaction) /* Just to make it beautiful enough */
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
{
/*
In case we were locking all tables, we did not start transaction
......
......@@ -49,6 +49,11 @@ static my_string opt_mysql_unix_port=0;
static my_string opt_ignore_lines=0;
#include <sslopt-vars.h>
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
static struct my_option my_long_options[] =
{
{"character-sets-dir", OPT_CHARSETS_DIR,
......@@ -112,8 +117,15 @@ static struct my_option my_long_options[] =
{"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
(gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
{"protocol", OPT_MYSQL_PROTOCOL,"The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replace", 'r', "If duplicate unique key was found, replace old row.",
(gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"silent", 's', "Be more silent.", (gptr*) &silent, (gptr*) &silent, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"socket", 'S', "Socket file to use for connection.",
......@@ -181,10 +193,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
#ifdef __WIN__
case 'W':
opt_mysql_unix_port=MYSQL_NAMEDPIPE;
opt_protocol = MYSQL_PROTOCOL_PIPE;
opt_local_file=1;
break;
#endif
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
......@@ -351,6 +372,12 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
database,opt_mysql_port,opt_mysql_unix_port,
......@@ -486,6 +513,9 @@ int main(int argc, char **argv)
exitcode = error;
db_disconnect(current_host, sock);
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
free_defaults(argv_to_free);
my_end(0);
return(exitcode);
......
......@@ -31,6 +31,11 @@ static my_string host=0,opt_password=0,user=0;
static my_bool opt_show_keys=0,opt_compress=0,opt_status=0, tty_password=0;
static uint opt_verbose=0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
static void get_options(int *argc,char ***argv);
static uint opt_mysql_port=0;
static int list_dbs(MYSQL *mysql,const char *wild);
......@@ -86,6 +91,12 @@ int main(int argc, char **argv)
if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath, opt_ssl_cipher);
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!(mysql_real_connect(&mysql,host,user,opt_password,
argv[0],opt_mysql_port,opt_mysql_unix_port,
......@@ -114,6 +125,9 @@ int main(int argc, char **argv)
mysql_close(&mysql); /* Close & free connection */
if (opt_password)
my_free(opt_password,MYF(0));
#ifdef HAVE_SMEM
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif
my_end(0);
exit(error ? 1 : 0);
return 0; /* No compiler warnings */
......@@ -147,6 +161,13 @@ static struct my_option my_long_options[] =
#ifdef __WIN__
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"protocol", OPT_MYSQL_PROTOCOL,"The protocol of connection (tcp,socket,pipe,memory)",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
......@@ -213,9 +234,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'W':
#ifdef __WIN__
opt_mysql_unix_port=MYSQL_NAMEDPIPE;
opt_protocol = MYSQL_PROTOCOL_PIPE;
#endif
break;
case OPT_MYSQL_PROTOCOL:
{
if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", argument);
exit(1);
}
break;
}
case '#':
DBUG_PUSH(argument ? argument : "d:t:o");
break;
......
......@@ -23,6 +23,8 @@
#include <io.h>
#include <malloc.h>
#define HAVE_SMEM 1
#if defined(__NT__)
#define SYSTEM_TYPE "NT"
#elif defined(__WIN2000__)
......@@ -311,3 +313,6 @@ inline double ulonglong2double(ulonglong value)
#define statistic_add(V,C,L) (V)+=(C)
#endif
#define statistic_increment(V,L) thread_safe_increment((V),(L))
#define shared_memory_buffer_length 16000
#define default_shared_memory_base_name "MYSQL";
......@@ -72,3 +72,15 @@ extern const char *client_errors[]; /* Error messages */
#define CR_INVALID_PARAMETER_NO 2032
#define CR_INVALID_BUFFER_USE 2033
#define CR_UNSUPPORTED_PARAM_TYPE 2034
#define CR_SHARED_MEMORY_CONNECTION 2035
#define CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR 2036
#define CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR 2037
#define CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR 2038
#define CR_SHARED_MEMORY_CONNECT_MAP_ERROR 2039
#define CR_SHARED_MEMORY_FILE_MAP_ERROR 2040
#define CR_SHARED_MEMORY_MAP_ERROR 2041
#define CR_SHARED_MEMORY_EVENT_ERROR 2042
#define CR_SHARED_MEMORY_CONNECT_ABANDODED_ERROR 2043
#define CR_SHARED_MEMORY_CONNECT_SET_ERROR 2046
#define CR_CONN_UNKNOW_PROTOCOL 2048
......@@ -37,6 +37,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#endif
#include <stdarg.h>
#include <typelib.h>
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
......@@ -247,12 +248,6 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */
my_string *wild; /* Pointer to wildcards */
} WF_PACK;
typedef struct st_typelib { /* Different types saved here */
uint count; /* How many types */
const char *name; /* Name of typelib */
const char **type_names;
} TYPELIB;
enum cache_type
{
READ_CACHE,WRITE_CACHE,
......@@ -558,6 +553,7 @@ extern char *_my_strdup_with_length(const byte *from, uint length,
const char *sFile, uint uLine,
myf MyFlag);
#ifndef TERMINATE
extern void TERMINATE(FILE *file);
#endif
......@@ -706,9 +702,6 @@ extern void freeze_size(DYNAMIC_ARRAY *array);
#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
#define push_dynamic(A,B) insert_dynamic(A,B)
extern int find_type(my_string x,TYPELIB *typelib,uint full_name);
extern void make_type(my_string to,uint nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,uint nr);
extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
uint init_alloc,uint alloc_increment);
extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
......
......@@ -56,6 +56,7 @@ typedef int my_socket;
#include "mysql_com.h"
#include "mysql_version.h"
#include "typelib.h"
extern unsigned int mysql_port;
extern char *mysql_unix_port;
......@@ -137,24 +138,36 @@ struct st_mysql_options {
a read that is replication-aware
*/
my_bool no_master_reads;
char *shared_memory_base_name;
unsigned int protocol;
};
enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS,
MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_LOCAL_INFILE};
enum mysql_option
{
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, MYSQL_INIT_COMMAND,
MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME
};
enum mysql_status { MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,
MYSQL_STATUS_USE_RESULT};
enum mysql_status
{
MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
};
enum mysql_protocol_type
{
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE,
MYSQL_PROTOCOL_MEMORY
};
/*
There are three types of queries - the ones that have to go to
the master, the ones that go to a slave, and the adminstrative
type which must happen on the pivot connectioin
*/
enum mysql_rpl_type { MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE,
MYSQL_RPL_ADMIN };
enum mysql_rpl_type
{
MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
};
typedef struct st_mysql
......
/* Copyright (C) 2000 MySQL 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 */
#ifndef _typelib_h
#define _typelib_h
typedef struct st_typelib { /* Different types saved here */
uint count; /* How many types */
const char *name; /* Name of typelib */
const char **type_names;
} TYPELIB;
extern int find_type(char *x,TYPELIB *typelib,uint full_name);
extern void make_type(char *to,uint nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,uint nr);
extern TYPELIB sql_protocol_typelib;
#endif /* _typelib_h */
......@@ -32,7 +32,7 @@ extern "C" {
#endif /* __cplusplus */
enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL};
VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL,VIO_TYPE_SHARED_MEMORY};
#ifndef __WIN__
#define HANDLE void *
......@@ -41,6 +41,9 @@ enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET,
Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
HANDLE event_server_wrote, HANDLE event_server_read,
HANDLE event_client_wrote, HANDLE event_client_read);
#endif
void vio_delete(Vio* vio);
......@@ -107,6 +110,17 @@ my_bool vio_poll_read(Vio *vio,uint timeout);
}
#endif
#ifdef HAVE_SMEM
int vio_read_shared_memory(Vio *vio, gptr buf, int size);
int vio_write_shared_memory(Vio *vio, const gptr buf, int size);
int vio_close_shared_memory(Vio * vio);
#endif
#ifdef __WIN__
int vio_read_pipe(Vio *vio, gptr buf, int size);
int vio_write_pipe(Vio *vio, const gptr buf, int size);
int vio_close_pipe(Vio * vio);
#endif
#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO)
#define vio_delete(vio) (vio)->viodelete(vio)
#define vio_errno(vio) (vio)->vioerrno(vio)
......@@ -233,6 +247,17 @@ struct st_vio
SSL* ssl_;
my_bool open_;
#endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM
HANDLE handle_file_map;
char *handle_map;
HANDLE event_server_wrote;
HANDLE event_server_read;
HANDLE event_client_wrote;
HANDLE event_client_read;
long shared_memory_remain;
char *shared_memory_pos;
NET *net;
#endif /* HAVE_SMEM */
#endif /* HAVE_VIO */
};
#endif /* EMBEDDED_LIBRARY */
......
......@@ -59,6 +59,17 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",
"Can't open shared memory. File mapping don't create (%lu)",
"Can't open shared memory. Map of memory don't create (%lu)",
"Can't open shared memory. File mapping don't create for client (%lu)",
"Can't open shared memory. Map of memory don't create for client (%lu)",
"Can't open shared memory. %s event don't create for client (%lu)",
"Can't open shared memory. Server abandoded and don't sent the answer event (%lu)",
"Can't open shared memory. Can't send the request event to server (%lu)"
"Wrong or unknow protocol"
};
/* Start of code added by Roberto M. Serqueira - martinsc@uol.com.br - 05.24.2001 */
......@@ -101,6 +112,17 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",
"Can't open shared memory. File mapping don't create (%lu)",
"Can't open shared memory. Map of memory don't create (%lu)",
"Can't open shared memory. File mapping don't create for client (%lu)",
"Can't open shared memory. Map of memory don't create for client (%lu)",
"Can't open shared memory. %s event don't create for client (%lu)",
"Can't open shared memory. Server abandoded and don't sent the answer event (%lu)",
"Can't open shared memory. Can't send the request event to server (%lu)"
"Wrong or unknow protocol"
};
#else /* ENGLISH */
......@@ -141,6 +163,17 @@ const char *client_errors[]=
"Invalid parameter number",
"Can't send long data for non string or binary data types (parameter: %d)",
"Using not supported parameter type: %d (parameter: %d)"
"Shared memory (%lu)",
"Can't open shared memory. Request event don't create (%lu)",
"Can't open shared memory. Answer event don't create (%lu)",
"Can't open shared memory. File mapping don't create (%lu)",
"Can't open shared memory. Map of memory don't create (%lu)",
"Can't open shared memory. File mapping don't create for client (%lu)",
"Can't open shared memory. Map of memory don't create for client (%lu)",
"Can't open shared memory. %s event don't create for client (%lu)",
"Can't open shared memory. Server abandoded and don't sent the answer event (%lu)",
"Can't open shared memory. Can't send the request event to server (%lu)"
"Wrong or unknow protocol"
};
#endif
......
......@@ -84,6 +84,15 @@ ulong net_write_timeout= NET_WRITE_TIMEOUT;
#define SOCKET_ERROR -1
#endif /* __WIN__ */
#ifdef HAVE_SMEM
char *shared_memory_base_name=0;
const char *def_shared_memory_base_name=default_shared_memory_base_name;
#endif
const char *sql_protocol_names_lib[] =
{ "TCP", "SOCKET", "PIPE", "MEMORY",NullS };
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
sql_protocol_names_lib};
/*
If allowed through some configuration, then this needs to
be changed
......@@ -336,6 +345,190 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
}
#endif
/*
Create new shared memory connection, return handler of connection
SYNOPSIS
create_shared_memory()
mysql Pointer of mysql structure
net Pointer of net structure
connect_timeout Timeout of connection
*/
#ifdef HAVE_SMEM
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
{
ulong smem_buffer_length = shared_memory_buffer_length + 4;
/*
event_connect_request is event object for start connection actions
event_connect_answer is event object for confirm, that server put data
handle_connect_file_map is file-mapping object, use for create shared memory
handle_connect_map is pointer on shared memory
handle_map is pointer on shared memory for client
event_server_wrote,
event_server_read,
event_client_wrote,
event_client_read are events for transfer data between server and client
handle_file_map is file-mapping object, use for create shared memory
*/
HANDLE event_connect_request = NULL;
HANDLE event_connect_answer = NULL;
HANDLE handle_connect_file_map = NULL;
char *handle_connect_map = NULL;
char *handle_map = NULL;
HANDLE event_server_wrote = NULL;
HANDLE event_server_read = NULL;
HANDLE event_client_wrote = NULL;
HANDLE event_client_read = NULL;
HANDLE handle_file_map = NULL;
ulong connect_number;
char connect_number_char[22], *p;
char tmp[64];
char *suffix_pos;
DWORD error_allow = 0;
DWORD error_code = 0;
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part
Where:
shared_memory_base_name is unique value for each server
unique_part is uniquel value for each object (events and file-mapping)
*/
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
strmov(suffix_pos, "CONNECT_REQUEST");
if ((event_connect_request = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
goto err;
}
strmov(suffix_pos, "CONNECT_ANSWER");
if ((event_connect_answer = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
goto err;
}
strmov(suffix_pos, "CONNECT_DATA");
if ((handle_connect_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
goto err;
}
if ((handle_connect_map = MapViewOfFile(handle_connect_file_map,FILE_MAP_WRITE,0,0,sizeof(DWORD))) == NULL)
{
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
goto err;
}
/*
Send to server request of connection
*/
if (!SetEvent(event_connect_request))
{
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
goto err;
}
/*
Wait of answer from server
*/
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) != WAIT_OBJECT_0)
{
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDODED_ERROR;
goto err;
}
/*
Get number of connection
*/
connect_number = uint4korr(handle_connect_map);/*WAX2*/
p = int2str(connect_number, connect_number_char, 10);
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part+number_of_connection
Where:
shared_memory_base_name is uniquel value for each server
unique_part is uniquel value for each object (events and file-mapping)
number_of_connection is number of connection between server and client
*/
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,"_",NullS);
strmov(suffix_pos, "DATA");
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
goto err2;
}
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,smem_buffer_length)) == NULL)
{
error_allow = CR_SHARED_MEMORY_MAP_ERROR;
goto err2;
}
strmov(suffix_pos, "SERVER_WROTE");
if ((event_server_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
goto err2;
}
strmov(suffix_pos, "SERVER_READ");
if ((event_server_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
goto err2;
}
strmov(suffix_pos, "CLIENT_WROTE");
if ((event_client_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
goto err2;
}
strmov(suffix_pos, "CLIENT_READ");
if ((event_client_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
{
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
goto err2;
}
/*
Set event that server should send data
*/
SetEvent(event_server_read);
err2:
if (error_allow == 0)
{
net->vio = vio_new_win32shared_memory(net,handle_file_map,handle_map,event_server_wrote,
event_server_read,event_client_wrote,event_client_read);
}
else
{
error_code = GetLastError();
if (event_server_read) CloseHandle(event_server_read);
if (event_server_wrote) CloseHandle(event_server_wrote);
if (event_client_read) CloseHandle(event_client_read);
if (event_client_wrote) CloseHandle(event_client_wrote);
if (handle_map) UnmapViewOfFile(handle_map);
if (handle_file_map) CloseHandle(handle_file_map);
}
err:
if (error_allow) error_code = GetLastError();
if (event_connect_request) CloseHandle(event_connect_request);
if (event_connect_answer) CloseHandle(event_connect_answer);
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
if (error_allow)
{
net->last_errno=error_allow;
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
sprintf(net->last_error,ER(net->last_errno),suffix_pos,error_code);
else
sprintf(net->last_error,ER(net->last_errno),error_code);
return(INVALID_HANDLE_VALUE);
}
return(handle_map);
};
#endif
/*****************************************************************************
read a packet from server. Give error message if socket was down
......@@ -734,7 +927,7 @@ static const char *default_options[]=
"character-sets-dir", "default-character-set", "interactive-timeout",
"connect-timeout", "local-infile", "disable-local-infile",
"replication-probe", "enable-reads-from-master", "repl-parse-query",
"ssl-cipher",
"ssl-cipher","protocol","shared_memory_base_name",
NullS
};
......@@ -794,9 +987,8 @@ static void mysql_read_default_options(struct st_mysql_options *options,
options->password=my_strdup(opt_arg,MYF(MY_WME));
}
break;
case 5: /* pipe */
options->named_pipe=1; /* Force named pipe */
break;
case 5:
options->protocol = MYSQL_PROTOCOL_PIPE;
case 20: /* connect_timeout */
case 6: /* timeout */
if (opt_arg)
......@@ -889,6 +1081,20 @@ static void mysql_read_default_options(struct st_mysql_options *options,
case 25: /* repl-parse-query */
options->rpl_parse= 1;
break;
case 27:/* protocol */
if ((options->protocol = find_type(opt_arg, &sql_protocol_typelib,0)) == ~(ulong) 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
exit(1);
}
break;
case 28: /*shared_memory_base_name*/
#ifdef HAVE_SMEM
if (options->shared_memory_base_name != def_shared_memory_base_name)
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
#endif
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
......@@ -1449,6 +1655,9 @@ mysql_init(MYSQL *mysql)
#ifdef ENABLED_LOCAL_INFILE
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
#endif
#ifdef HAVE_SMEM
mysql->options.shared_memory_base_name=(char*)def_shared_memory_base_name;
#endif
return mysql;
}
......@@ -1645,9 +1854,38 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/*
** Grab a socket and connect it to the server
*/
#if defined(HAVE_SMEM)
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)&&
(!host || !strcmp(host,LOCAL_HOST)))
{
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
INVALID_HANDLE_VALUE)
{
DBUG_PRINT("error",
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
host ? host : "<null>",
unix_socket ? unix_socket : "<null>",
(int) mysql->options.shared_memory_base_name,
(int) have_tcpip));
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
goto error;
/*
Try also with PIPE or TCP/IP
*/
}
else
{
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
sock=0;
unix_socket = 0;
host=mysql->options.shared_memory_base_name;
host_info=(char*) ER(CR_SHARED_MEMORY_CONNECTION);
}
} else
#endif //HAVE_SMEM
#if defined(HAVE_SYS_UN_H)
if ((!host || !strcmp(host,LOCAL_HOST)) && (unix_socket || mysql_unix_port))
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_SOCKET)&&
(!host || !strcmp(host,LOCAL_HOST)) && (unix_socket || mysql_unix_port))
{
host=LOCAL_HOST;
if (!unix_socket)
......@@ -1672,46 +1910,42 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno);
goto error;
}
else
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
}
else
#elif defined(__WIN__)
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_PIPE)&&
((unix_socket || !host && is_NT() ||
host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) ||!have_tcpip))&&(!net->vio))
{
if ((unix_socket ||
!host && is_NT() ||
host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) ||
mysql->options.named_pipe || !have_tcpip))
sock=0;
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout,
(char**) &host, (char**) &unix_socket)) ==
INVALID_HANDLE_VALUE)
{
sock=0;
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout,
(char**) &host, (char**) &unix_socket)) ==
INVALID_HANDLE_VALUE)
{
DBUG_PRINT("error",
("host: '%s' socket: '%s' named_pipe: %d have_tcpip: %d",
host ? host : "<null>",
unix_socket ? unix_socket : "<null>",
(int) mysql->options.named_pipe,
(int) have_tcpip));
if (mysql->options.named_pipe ||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
{
net->last_errno= CR_SERVER_LOST;
strmov(net->last_error,ER(net->last_errno));
goto error; /* User only requested named pipes */
}
/* Try also with TCP/IP */
}
else
{
net->vio=vio_new_win32pipe(hPipe);
sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
unix_socket);
}
DBUG_PRINT("error",
("host: '%s' socket: '%s' have_tcpip: %d",
host ? host : "<null>",
unix_socket ? unix_socket : "<null>",
(int) have_tcpip));
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
goto error;
/*
Try also with TCP/IP
*/
}
else
{
net->vio=vio_new_win32pipe(hPipe);
sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
unix_socket);
}
}
if (hPipe == INVALID_HANDLE_VALUE)
#endif
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_TCP)&&(!net->vio))
{
unix_socket=0; /* This is not used */
if (!port)
......@@ -1766,6 +2000,14 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
goto error;
}
}
else
if (!net->vio)
{
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
net->last_errno= CR_CONN_UNKNOW_PROTOCOL;
sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL));
goto error;
};
if (!net->vio || my_net_init(net, net->vio))
{
......@@ -2169,6 +2411,10 @@ mysql_close(MYSQL *mysql)
#ifdef HAVE_OPENSSL
mysql_ssl_free(mysql);
#endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_SMEM */
/* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
bzero((char*) &mysql->options,sizeof(mysql->options));
......@@ -2888,7 +3134,7 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
mysql->options.compress= 1; /* Remember for connect */
break;
case MYSQL_OPT_NAMED_PIPE:
mysql->options.named_pipe=1; /* Force named pipe */
mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
if (!arg || test(*(uint*) arg))
......@@ -2916,6 +3162,16 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
break;
case MYSQL_OPT_PROTOCOL:
mysql->options.protocol= *(uint*) arg;
break;
case MYSQL_SHARED_MEMORY_BASE_NAME:
#ifdef HAVE_SMEM
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
#endif
break;
default:
DBUG_RETURN(1);
}
......
......@@ -179,10 +179,13 @@ static char szPipeName [ 257 ];
static SECURITY_ATTRIBUTES saPipeSecurity;
static SECURITY_DESCRIPTOR sdPipeDescriptor;
static HANDLE hPipe = INVALID_HANDLE_VALUE;
static pthread_cond_t COND_handler_count;
static uint handler_count;
static bool opt_enable_named_pipe = 0;
#endif
#ifdef __WIN__
static bool opt_console=0,start_mode=0;
static pthread_cond_t COND_handler_count;
static uint handler_count;
static bool opt_console=0, start_mode=0, use_opt_args;
static int opt_argc;
static char **opt_argv;
......@@ -335,6 +338,11 @@ ulong query_cache_limit=0;
Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
static char *shared_memory_base_name=default_shared_memory_base_name;
static bool opt_enable_shared_memory = 0;
#endif
volatile ulong cached_thread_count=0;
// replication parameters, if master_host is not NULL, we are a slave
......@@ -459,6 +467,9 @@ static bool read_init_file(char *file_name);
#ifdef __NT__
static pthread_handler_decl(handle_connections_namedpipes,arg);
#endif
#ifdef HAVE_SMEM
static pthread_handler_decl(handle_connections_shared_memory,arg);
#endif
extern pthread_handler_decl(handle_slave,arg);
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit);
......@@ -2123,21 +2134,24 @@ The server will not act as a slave.");
printf(ER(ER_READY),my_progname,server_version,"");
fflush(stdout);
#if defined(__NT__) || defined(HAVE_SMEM)
#ifdef __NT__
if (hPipe == INVALID_HANDLE_VALUE &&
(!have_tcpip || opt_disable_networking))
(!have_tcpip || opt_disable_networking) &&
!opt_enable_shared_memory)
{
sql_print_error("TCP/IP or --enable-named-pipe should be configured on NT OS");
sql_print_error("TCP/IP,--shared-memory or --named-pipe should be configured on NT OS");
unireg_abort(1);
}
else
#endif
{
pthread_mutex_lock(&LOCK_thread_count);
(void) pthread_cond_init(&COND_handler_count,NULL);
{
pthread_t hThread;
handler_count=0;
#ifdef __NT__
if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
{
handler_count++;
......@@ -2148,18 +2162,33 @@ The server will not act as a slave.");
handler_count--;
}
}
#endif
#ifdef HAVE_SMEM
if (opt_enable_shared_memory)
{
handler_count++;
if (pthread_create(&hThread,&connection_attrib,
handle_connections_shared_memory, 0))
{
sql_print_error("Warning: Can't create thread to handle shared memory");
handler_count--;
}
}
#endif
if (have_tcpip && !opt_disable_networking)
{
handler_count++;
if (pthread_create(&hThread,&connection_attrib,
handle_connections_sockets, 0))
{
sql_print_error("Warning: Can't create thread to handle named pipes");
sql_print_error("Warning: Can't create thread to handle tcp/ip");
handler_count--;
}
}
while (handler_count > 0)
{
pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
}
}
pthread_mutex_unlock(&LOCK_thread_count);
}
......@@ -2777,6 +2806,219 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
}
#endif /* __NT__ */
/*
Thread of shared memory's service
SYNOPSIS
pthread_handler_decl()
handle_connections_shared_memory Thread handle
arg Arguments of thread
*/
#ifdef HAVE_SMEM
pthread_handler_decl(handle_connections_shared_memory,arg)
{
/*
event_connect_request is event object for start connection actions
event_connect_answer is event object for confirm, that server put data
handle_connect_file_map is file-mapping object, use for create shared memory
handle_connect_map is pointer on shared memory
handle_map is pointer on shared memory for client
event_server_wrote,
event_server_read,
event_client_wrote,
event_client_read are events for transfer data between server and client
handle_file_map is file-mapping object, use for create shared memory
*/
HANDLE handle_connect_file_map = NULL;
char *handle_connect_map = NULL;
HANDLE event_connect_request = NULL;
HANDLE event_connect_answer = NULL;
ulong smem_buffer_length = shared_memory_buffer_length + 4;
ulong connect_number = 1;
my_bool error_allow;
THD *thd;
char tmp[63];
char *suffix_pos;
char connect_number_char[22], *p;
my_thread_init();
DBUG_ENTER("handle_connections_shared_memorys");
DBUG_PRINT("general",("Waiting for allocated shared memory."));
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part
Where:
shared_memory_base_name is unique value for each server
unique_part is unique value for each object (events and file-mapping)
*/
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
strmov(suffix_pos, "CONNECT_REQUEST");
if ((event_connect_request = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create shared memory service ! The request event don't create.");
goto error;
}
strmov(suffix_pos, "CONNECT_ANSWER");
if ((event_connect_answer = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create shared memory service ! The answer event don't create.");
goto error;
}
strmov(suffix_pos, "CONNECT_DATA");
if ((handle_connect_file_map = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,
0,sizeof(connect_number),tmp)) == 0)
{
sql_perror("Can't create shared memory service ! File mapping don't create.");
goto error;
}
if ((handle_connect_map = (char *)MapViewOfFile(handle_connect_file_map,FILE_MAP_WRITE,0,0,
sizeof(DWORD))) == 0)
{
sql_perror("Can't create shared memory service ! Map of memory don't create.");
goto error;
}
while (!abort_loop)
{
/*
Wait a request from client
*/
WaitForSingleObject(event_connect_request,INFINITE);
error_allow = FALSE;
HANDLE handle_client_file_map = NULL;
char *handle_client_map = NULL;
HANDLE event_client_wrote = NULL;
HANDLE event_client_read = NULL;
HANDLE event_server_wrote = NULL;
HANDLE event_server_read = NULL;
p = int2str(connect_number, connect_number_char, 10);
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part+number_of_connection
Where:
shared_memory_base_name is uniquel value for each server
unique_part is unique value for each object (events and file-mapping)
number_of_connection is number of connection between server and client
*/
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,"_",NullS);
strmov(suffix_pos, "DATA");
if ((handle_client_file_map = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,
PAGE_READWRITE,0,smem_buffer_length,tmp)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! File mapping don't create.");
error_allow = TRUE;
goto errorconn;
}
if ((handle_client_map = (char*)MapViewOfFile(handle_client_file_map,FILE_MAP_WRITE,0,0,smem_buffer_length)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! Map of memory don't create.");
error_allow = TRUE;
goto errorconn;
}
strmov(suffix_pos, "CLIENT_WROTE");
if ((event_client_wrote = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! CW event don't create.");
error_allow = TRUE;
goto errorconn;
}
strmov(suffix_pos, "CLIENT_READ");
if ((event_client_read = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! CR event don't create.");
error_allow = TRUE;
goto errorconn;
}
strmov(suffix_pos, "SERVER_READ");
if ((event_server_read = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! SR event don't create.");
error_allow = TRUE;
goto errorconn;
}
strmov(suffix_pos, "SERVER_WROTE");
if ((event_server_wrote = CreateEvent(NULL,FALSE,FALSE,tmp)) == 0)
{
sql_perror("Can't create connection with client in shared memory service ! SW event don't create.");
error_allow = TRUE;
goto errorconn;
}
if (abort_loop) break;
if ( !(thd = new THD))
{
error_allow = TRUE;
goto errorconn;
}
/*
Send number of connection to client
*/
int4store(handle_connect_map, connect_number);
/*
Send number of connection to client
*/
if (!SetEvent(event_connect_answer))
{
sql_perror("Can't create connection with client in shared memory service ! Can't send answer event.");
error_allow = TRUE;
goto errorconn;
}
/*
Set event that client should receive data
*/
if (!SetEvent(event_client_read))
{
sql_perror("Can't create connection with client in shared memory service ! Can't set client to read's mode.");
error_allow = TRUE;
goto errorconn;
}
if (!(thd->net.vio = vio_new_win32shared_memory(&thd->net,handle_client_file_map,handle_client_map,event_client_wrote,
event_client_read,event_server_wrote,event_server_read)) ||
my_net_init(&thd->net, thd->net.vio))
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES);
delete thd;
error_allow = TRUE;
}
/* host name is unknown */
errorconn:
if (error_allow)
{
if (!handle_client_map) UnmapViewOfFile(handle_client_map);
if (!handle_client_file_map) CloseHandle(handle_client_file_map);
if (!event_server_wrote) CloseHandle(event_server_wrote);
if (!event_server_read) CloseHandle(event_server_read);
if (!event_client_wrote) CloseHandle(event_client_wrote);
if (!event_client_read) CloseHandle(event_client_read);
continue;
}
thd->host = my_strdup(localhost,MYF(0)); /* Host is unknown */
create_new_thread(thd);
uint4korr(connect_number++);
}
error:
if (!handle_connect_map) UnmapViewOfFile(handle_connect_map);
if (!handle_connect_file_map) CloseHandle(handle_connect_file_map);
if (!event_connect_answer) CloseHandle(event_connect_answer);
if (!event_connect_request) CloseHandle(event_connect_request);
pthread_mutex_lock(&LOCK_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_RETURN(0);
}
#endif /* HAVE_SMEM */
/******************************************************************************
** handle start options
......@@ -2886,7 +3128,9 @@ enum options {
OPT_INNODB_FORCE_RECOVERY,
OPT_BDB_CACHE_SIZE,
OPT_BDB_LOG_BUFFER_SIZE,
OPT_BDB_MAX_LOCK
OPT_BDB_MAX_LOCK,
OPT_ENABLE_SHARED_MEMORY,
OPT_SHARED_MEMORY_BASE_NAME
};
......@@ -2993,6 +3237,11 @@ struct my_option my_long_options[] =
{"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure",
(gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared-memory", OPT_ENABLE_SHARED_MEMORY,
"Enable the shared memory.",(gptr*) &opt_enable_shared_memory, (gptr*) &opt_enable_shared_memory,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0,
......@@ -3234,6 +3483,11 @@ struct my_option my_long_options[] =
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared_memory_base_name",OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
"Show user and password in SHOW SLAVE STATUS",
(gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0,
......
......@@ -520,6 +520,10 @@ struct show_var_st init_vars[]= {
{sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS},
#endif /* HAVE_QUERY_CACHE */
{sys_safe_show_db.name, (char*) &sys_safe_show_db, SHOW_SYS},
#ifdef HAVE_SMEM
{"shared_memory", (char*) &opt_enable_shared_memory, SHOW_MY_BOOL},
{"shared_memory_base_name", (char*) &shared_memory_base_name, SHOW_CHAR_PTR},
#endif
{sys_server_id.name, (char*) &sys_server_id, SHOW_SYS},
{sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS},
{"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
......
......@@ -45,7 +45,43 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
vio->sd = sd;
vio->hPipe = hPipe;
vio->localhost= localhost;
#ifdef HAVE_VIO
#ifdef HAVE_VIO
#ifdef __WIN__
if (type == VIO_TYPE_NAMEDPIPE)
{
vio->viodelete =vio_delete;
vio->vioerrno =vio_errno;
vio->read =vio_read_pipe;
vio->write =vio_write_pipe;
vio->fastsend =vio_fastsend;
vio->viokeepalive =vio_keepalive;
vio->should_retry =vio_should_retry;
vio->vioclose =vio_close_pipe;
vio->peer_addr =vio_peer_addr;
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
}
else /* default is VIO_TYPE_TCPIP */
#endif
#ifdef HAVE_SMEM
if (type == VIO_TYPE_SHARED_MEMORY)
{
vio->viodelete =vio_delete;
vio->vioerrno =vio_errno;
vio->read =vio_read_shared_memory;
vio->write =vio_write_shared_memory;
vio->fastsend =vio_fastsend;
vio->viokeepalive =vio_keepalive;
vio->should_retry =vio_should_retry;
vio->vioclose =vio_close_shared_memory;
vio->peer_addr =vio_peer_addr;
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
}
else
#endif
#ifdef HAVE_OPENSSL
if (type == VIO_TYPE_SSL)
{
......@@ -131,4 +167,44 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
DBUG_RETURN(vio);
}
#ifdef HAVE_SMEM
Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
HANDLE event_server_wrote, HANDLE event_server_read,
HANDLE event_client_wrote, HANDLE event_client_read)
{
Vio *vio;
DBUG_ENTER("vio_new_win32shared_memory");
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
{
vio_reset(vio, VIO_TYPE_SHARED_MEMORY, 0, 0, TRUE);
vio->handle_file_map = handle_file_map;
vio->handle_map = handle_map;
vio->event_server_wrote = event_server_wrote;
vio->event_server_read = event_server_read;
vio->event_client_wrote = event_client_wrote;
vio->event_client_read = event_client_read;
vio->shared_memory_remain = 0;
vio->shared_memory_pos = handle_map;
vio->net = net;
strmov(vio->desc, "shared memory");
}
DBUG_RETURN(vio);
}
#endif
#endif
void vio_delete(Vio* vio)
{
/* It must be safe to delete null pointers. */
/* This matches the semantics of C++'s delete operator. */
if (vio)
{
if (vio->type != VIO_CLOSED)
#ifdef HAVE_VIO /*WAX*/
vio->vioclose(vio);
#else
vio_close(vio);
#endif
my_free((gptr) vio,MYF(0));
}
}
......@@ -35,18 +35,6 @@
#define HANDLE void *
#endif
void vio_delete(Vio* vio)
{
/* It must be safe to delete null pointers. */
/* This matches the semantics of C++'s delete operator. */
if (vio)
{
if (vio->type != VIO_CLOSED)
vio_close(vio);
my_free((gptr) vio,MYF(0));
}
}
int vio_errno(Vio *vio __attribute__((unused)))
{
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
......@@ -58,14 +46,8 @@ int vio_read(Vio * vio, gptr buf, int size)
int r;
DBUG_ENTER("vio_read");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
#ifdef __WIN__
if (vio->type == VIO_TYPE_NAMEDPIPE)
{
DWORD length;
if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
DBUG_RETURN(-1);
DBUG_RETURN(length);
}
r = recv(vio->sd, buf, size,0);
#else
errno=0; /* For linux */
......@@ -87,15 +69,8 @@ int vio_write(Vio * vio, const gptr buf, int size)
int r;
DBUG_ENTER("vio_write");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
#if defined( __WIN__)
if ( vio->type == VIO_TYPE_NAMEDPIPE)
{
DWORD length;
if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
DBUG_RETURN(-1);
DBUG_RETURN(length);
}
r = send(vio->sd, buf, size, 0);
#ifdef __WIN__
r = send(vio->sd, buf, size,0);
#else
r = write(vio->sd, buf, size);
#endif /* __WIN__ */
......@@ -109,7 +84,6 @@ int vio_write(Vio * vio, const gptr buf, int size)
DBUG_RETURN(r);
}
int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode,
my_bool *old_mode)
{
......@@ -332,3 +306,155 @@ my_bool vio_poll_read(Vio *vio,uint timeout)
DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
#endif
}
#ifdef __WIN__
int vio_read_pipe(Vio * vio, gptr buf, int size)
{
DWORD length;
DBUG_ENTER("vio_read_pipe");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
DBUG_RETURN(-1);
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN(length);
}
int vio_write_pipe(Vio * vio, const gptr buf, int size)
{
DWORD length;
DBUG_ENTER("vio_write_pipe");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
DBUG_RETURN(-1);
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN(length);
}
int vio_close_pipe(Vio * vio)
{
int r;
DBUG_ENTER("vio_close_pipe");
#if defined(__NT__) && defined(MYSQL_SERVER)
CancelIo(vio->hPipe);
DisconnectNamedPipe(vio->hPipe);
#endif
r=CloseHandle(vio->hPipe);
if (r)
{
DBUG_PRINT("vio_error", ("close() failed, error: %d",GetLastError()));
/* FIXME: error handling (not critical for MySQL) */
}
vio->type= VIO_CLOSED;
vio->sd= -1;
DBUG_RETURN(r);
}
#ifdef HAVE_SMEM
int vio_read_shared_memory(Vio * vio, gptr buf, int size)
{
int length;
int remain_local;
char *current_postion;
DBUG_ENTER("vio_read_shared_memory");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
remain_local = size;
current_postion=buf;
do
{
if (vio->shared_memory_remain == 0)
{
if (WaitForSingleObject(vio->event_server_wrote,vio->net->read_timeout*1000) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
vio->shared_memory_pos = vio->handle_map;
vio->shared_memory_remain = uint4korr((ulong*)vio->shared_memory_pos);
vio->shared_memory_pos+=4;
}
length = size;
if (vio->shared_memory_remain < length)
length = vio->shared_memory_remain;
if (length > remain_local)
length = remain_local;
memcpy(current_postion,vio->shared_memory_pos,length);
vio->shared_memory_remain-=length;
vio->shared_memory_pos+=length;
current_postion+=length;
remain_local-=length;
if (!vio->shared_memory_remain)
if (!SetEvent(vio->event_client_read)) DBUG_RETURN(-1);
} while (remain_local);
length = size;
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN(length);
}
int vio_write_shared_memory(Vio * vio, const gptr buf, int size)
{
int length;
uint remain;
HANDLE pos;
int sz;
char *current_postion;
DBUG_ENTER("vio_write_shared_memory");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
remain = size;
current_postion = buf;
while (remain != 0)
{
if (WaitForSingleObject(vio->event_server_read,vio->net->write_timeout*1000) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
sz = remain > shared_memory_buffer_length ? shared_memory_buffer_length: remain;
int4store(vio->handle_map,sz);
pos = vio->handle_map + 4;
memcpy(pos,current_postion,sz);
remain-=sz;
current_postion+=sz;
if (!SetEvent(vio->event_client_wrote)) DBUG_RETURN(-1);
}
length = size;
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN(length);
}
int vio_close_shared_memory(Vio * vio)
{
int r;
DBUG_ENTER("vio_close_shared_memory");
r=UnmapViewOfFile(vio->handle_map) || CloseHandle(vio->event_server_wrote) ||
CloseHandle(vio->event_server_read) || CloseHandle(vio->event_client_wrote) ||
CloseHandle(vio->event_client_read) || CloseHandle(vio->handle_file_map);
if (r)
{
DBUG_PRINT("vio_error", ("close() failed, error: %d",r));
/* FIXME: error handling (not critical for MySQL) */
}
vio->type= VIO_CLOSED;
vio->sd= -1;
DBUG_RETURN(r);
}
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment