Commit b40aed07 authored by Alexander Nozdrin's avatar Alexander Nozdrin

Auto-merge from mysql-5.1.

parents 0fd7ff87 2377eed3
......@@ -78,6 +78,9 @@ static const char* host = 0;
static int port= 0;
static uint my_end_arg;
static const char* sock= 0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name= 0;
#endif
static const char* user = 0;
static char* pass = 0;
static char *charset= 0;
......@@ -1075,6 +1078,12 @@ static struct my_option my_long_options[] =
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES character_set' to the output.", (uchar**) &charset,
(uchar**) &charset, 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.", (uchar**) &shared_memory_base_name,
(uchar**) &shared_memory_base_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"short-form", 's', "Just show regular queries: no extra info and no "
"row-based events. This is for testing only, and should not be used in "
"production systems. If you want to suppress base64-output, consider "
......@@ -1377,6 +1386,11 @@ static Exit_status safe_connect()
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, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
......
......@@ -81,6 +81,9 @@ enum {
static int record= 0, opt_sleep= -1;
static char *opt_db= 0, *opt_pass= 0;
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
......@@ -4896,6 +4899,8 @@ do_handle_error:
<opts> - options to use for the connection
* SSL - use SSL if available
* COMPRESS - use compression if available
* SHM - use shared memory if available
* PIPE - use named pipe if available
*/
......@@ -4904,6 +4909,7 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
my_bool con_pipe= 0, con_shm= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
......@@ -4914,6 +4920,9 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_port;
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
#ifdef HAVE_SMEM
static DYNAMIC_STRING ds_shm;
#endif
const struct command_arg connect_args[] = {
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
......@@ -4941,6 +4950,11 @@ void do_connect(struct st_command *command)
die("Illegal argument for port: '%s'", ds_port.str);
}
#ifdef HAVE_SMEM
/* Shared memory */
init_dynamic_string(&ds_shm, ds_sock.str, 0, 0);
#endif
/* Sock */
if (ds_sock.length)
{
......@@ -4979,6 +4993,10 @@ void do_connect(struct st_command *command)
con_ssl= 1;
else if (!strncmp(con_options, "COMPRESS", 8))
con_compress= 1;
else if (!strncmp(con_options, "PIPE", 4))
con_pipe= 1;
else if (!strncmp(con_options, "SHM", 3))
con_shm= 1;
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
......@@ -5026,6 +5044,31 @@ void do_connect(struct st_command *command)
}
#endif
#ifdef __WIN__
if (con_pipe)
{
uint protocol= MYSQL_PROTOCOL_PIPE;
mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
}
#endif
#ifdef HAVE_SMEM
if (con_shm)
{
uint protocol= MYSQL_PROTOCOL_MEMORY;
if (!ds_shm.length)
die("Missing shared memory base name");
mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
}
else if(shared_memory_base_name)
{
mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
shared_memory_base_name);
}
#endif
/* Use default db name */
if (ds_database.length == 0)
dynstr_set(&ds_database, opt_db);
......@@ -5058,6 +5101,9 @@ void do_connect(struct st_command *command)
dynstr_free(&ds_port);
dynstr_free(&ds_sock);
dynstr_free(&ds_options);
#ifdef HAVE_SMEM
dynstr_free(&ds_shm);
#endif
DBUG_VOID_RETURN;
}
......@@ -5724,6 +5770,12 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
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.", (uchar**) &shared_memory_base_name,
(uchar**) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
#endif
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
......@@ -7673,6 +7725,11 @@ int main(int argc, char **argv)
}
#endif
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
if (!(con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
......
......@@ -44,7 +44,7 @@ enum enum_vio_type
Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
HANDLE handle_map,
HANDLE event_server_wrote,
HANDLE event_server_read,
......@@ -221,7 +221,11 @@ struct st_vio
HANDLE event_conn_closed;
size_t shared_memory_remain;
char *shared_memory_pos;
NET *net;
#endif /* HAVE_SMEM */
#ifdef _WIN32
OVERLAPPED pipe_overlapped;
DWORD read_timeout_millis;
DWORD write_timeout_millis;
#endif
};
#endif /* vio_violite_h_ */
......@@ -7,6 +7,7 @@ use Carp;
use My::Config;
use My::Find;
use My::Platform;
use File::Basename;
......@@ -218,6 +219,12 @@ my @mysqld_rules=
{ 'ssl-key' => \&fix_ssl_server_key },
);
if (IS_WINDOWS)
{
# For simplicity, we use the same names for shared memory and
# named pipes.
push(@mysqld_rules, {'shared-memory-base-name' => \&fix_socket});
}
sub fix_ndb_mgmd_port {
my ($self, $config, $group_name, $group)= @_;
......@@ -347,6 +354,16 @@ sub post_check_client_group {
}
$config->insert($client_group_name, $name_to, $option->value())
}
if (IS_WINDOWS)
{
# Shared memory base may or may not be defined (e.g not defined in embedded)
my $shm = $group_to_copy_from->option("shared-memory-base-name");
if (defined $shm)
{
$config->insert($client_group_name,"shared-memory-base-name", $shm->value());
}
}
}
......@@ -393,6 +410,7 @@ sub post_check_embedded_group {
(
'#log-error', # Embedded server writes stderr to mysqltest's log file
'slave-net-timeout', # Embedded server are not build with replication
'shared-memory-base-name', # No shared memory for embedded
);
foreach my $option ( $mysqld->options(), $first_mysqld->options() ) {
......
......@@ -9,6 +9,11 @@ if (`SELECT '$nmp' != 'ON'`){
skip No named pipe support;
}
# Connect using named pipe for testing
connect(pipe_con,localhost,root,,,,,PIPE);
# Source select test case
-- source include/common-tests.inc
connection default;
disconnect pipe_con;
......@@ -389,7 +389,7 @@ HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
0,
NULL,
OPEN_EXISTING,
0,
FILE_FLAG_OVERLAPPED,
NULL )) != INVALID_HANDLE_VALUE)
break;
if (GetLastError() != ERROR_PIPE_BUSY)
......@@ -623,7 +623,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
err2:
if (error_allow == 0)
{
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
net->vio= vio_new_win32shared_memory(handle_file_map,handle_map,
event_server_wrote,
event_server_read,event_client_wrote,
event_client_read,event_conn_closed);
......@@ -2028,7 +2028,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
}
else
{
net->vio=vio_new_win32pipe(hPipe);
net->vio= vio_new_win32pipe(hPipe);
my_snprintf(host_info=buff, sizeof(buff)-1,
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
}
......
......@@ -1729,7 +1729,7 @@ static void network_init(void)
saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
......@@ -5281,17 +5281,26 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
pthread_handler_t handle_connections_namedpipes(void *arg)
{
HANDLE hConnectedPipe;
BOOL fConnected;
OVERLAPPED connectOverlapped = {0};
THD *thd;
my_thread_init();
DBUG_ENTER("handle_connections_namedpipes");
(void) my_pthread_getprio(pthread_self()); // For debugging
connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DBUG_PRINT("general",("Waiting for named pipe connections."));
while (!abort_loop)
{
/* wait for named pipe connection */
fConnected = ConnectNamedPipe(hPipe, NULL);
BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
{
/*
ERROR_IO_PENDING says async IO has started but not yet finished.
GetOverlappedResult will wait for completion.
*/
DWORD bytes;
fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
}
if (abort_loop)
break;
if (!fConnected)
......@@ -5300,7 +5309,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
{
CloseHandle(hPipe);
if ((hPipe= CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
......@@ -5320,7 +5329,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
hConnectedPipe = hPipe;
/* create new pipe for new connection */
if ((hPipe = CreateNamedPipe(pipe_name,
PIPE_ACCESS_DUPLEX,
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
......@@ -5342,7 +5351,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
CloseHandle(hConnectedPipe);
continue;
}
if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
my_net_init(&thd->net, thd->net.vio))
{
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
......@@ -5353,7 +5362,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
create_new_thread(thd);
}
CloseHandle(connectOverlapped.hEvent);
decrement_handler_count();
DBUG_RETURN(0);
}
......@@ -5530,8 +5539,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
errmsg= "Could not set client to read mode";
goto errorconn;
}
if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
handle_client_file_map,
if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
handle_client_map,
event_client_wrote,
event_client_read,
......
......@@ -46,6 +46,9 @@ static char *opt_user= 0;
static char *opt_password= 0;
static char *opt_host= 0;
static char *opt_unix_socket= 0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name= 0;
#endif
static unsigned int opt_port;
static my_bool tty_password= 0, opt_silent= 0;
......@@ -230,6 +233,26 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
}
}
/*
Enhanced version of mysql_client_init(), which may also set shared memory
base on Windows.
*/
static MYSQL *mysql_client_init(MYSQL* con)
{
MYSQL* res = mysql_init(con);
#ifdef HAVE_SMEM
if (res && shared_memory_base_name)
mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
#endif
return res;
}
/*
Disable direct calls of mysql_init, as it disregards shared memory base.
*/
#define mysql_init(A) Please use mysql_client_init instead of mysql_init
/* Check if the connection has InnoDB tables */
static my_bool check_have_innodb(MYSQL *conn)
......@@ -293,10 +316,10 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
fprintf(stdout, "\n Establishing a connection to '%s' ...",
opt_host ? opt_host : "");
if (!(mysql= mysql_init(NULL)))
if (!(mysql= mysql_client_init(NULL)))
{
opt_silent= 0;
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
/* enable local infile, in non-binary builds often disabled by default */
......@@ -1160,9 +1183,9 @@ static my_bool thread_query(char *query)
error= 0;
if (!opt_silent)
fprintf(stdout, "\n in thread_query(%s)", query);
if (!(l_mysql= mysql_init(NULL)))
if (!(l_mysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
return 1;
}
if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
......@@ -2512,9 +2535,9 @@ static void test_ps_query_cache()
case TEST_QCACHE_ON_WITH_OTHER_CONN:
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
printf("mysql_init() failed");
printf("mysql_client_init() failed");
DIE_UNLESS(0);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
......@@ -4960,9 +4983,9 @@ static void test_stmt_close()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
......@@ -5851,9 +5874,9 @@ DROP TABLE IF EXISTS test_multi_tab";
rc= mysql_more_results(mysql);
DIE_UNLESS(rc == 0);
if (!(mysql_local= mysql_init(NULL)))
if (!(mysql_local= mysql_client_init(NULL)))
{
fprintf(stdout, "\n mysql_init() failed");
fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
......@@ -5976,9 +5999,9 @@ static void test_prepare_multi_statements()
char query[MAX_TEST_QUERY_LENGTH];
myheader("test_prepare_multi_statements");
if (!(mysql_local= mysql_init(NULL)))
if (!(mysql_local= mysql_client_init(NULL)))
{
fprintf(stderr, "\n mysql_init() failed");
fprintf(stderr, "\n mysql_client_init() failed");
exit(1);
}
......@@ -7459,9 +7482,9 @@ static void test_prepare_grant()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
......@@ -7915,9 +7938,9 @@ static void test_drop_temp()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
......@@ -13159,7 +13182,7 @@ static void test_bug15518()
int rc;
myheader("test_bug15518");
mysql1= mysql_init(NULL);
mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
......@@ -13315,9 +13338,9 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
......@@ -13856,7 +13879,7 @@ static void test_bug9992()
if (!opt_silent)
printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
mysql1= mysql_init(NULL);
mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
......@@ -14445,9 +14468,9 @@ static void test_bug12001()
myheader("test_bug12001");
if (!(mysql_local= mysql_init(NULL)))
if (!(mysql_local= mysql_client_init(NULL)))
{
fprintf(stdout, "\n mysql_init() failed");
fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
......@@ -15172,9 +15195,9 @@ static void test_opt_reconnect()
myheader("test_opt_reconnect");
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
exit(1);
}
......@@ -15209,9 +15232,9 @@ static void test_opt_reconnect()
mysql_close(lmysql);
if (!(lmysql= mysql_init(NULL)))
if (!(lmysql= mysql_client_init(NULL)))
{
myerror("mysql_init() failed");
myerror("mysql_client_init() failed");
DIE_UNLESS(0);
}
......@@ -15246,7 +15269,7 @@ static void test_bug12744()
int rc;
myheader("test_bug12744");
lmysql= mysql_init(NULL);
lmysql= mysql_client_init(NULL);
DIE_UNLESS(lmysql);
if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
......@@ -15819,7 +15842,7 @@ static void test_bug15752()
rc= mysql_query(mysql, "create procedure p1() select 1");
myquery(rc);
mysql_init(&mysql_local);
mysql_client_init(&mysql_local);
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket,
......@@ -16705,7 +16728,7 @@ static void test_bug29692()
{
MYSQL* conn;
if (!(conn= mysql_init(NULL)))
if (!(conn= mysql_client_init(NULL)))
{
myerror("test_bug29692 init failed");
exit(1);
......@@ -16840,7 +16863,7 @@ static void test_bug30472()
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
......@@ -17014,7 +17037,7 @@ static void test_bug20023()
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
......@@ -17151,7 +17174,7 @@ static void bug31418_impl()
/* Create a new connection. */
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
......@@ -18001,7 +18024,7 @@ static void test_bug44495()
"END;");
myquery(rc);
DIE_UNLESS(mysql_init(&con));
DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
current_db, opt_port, opt_unix_socket,
......@@ -18064,6 +18087,11 @@ static struct my_option client_test_long_options[] =
0, 0, 0, 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", 'm', "Base name of shared memory.",
(uchar**) &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"socket", 'S', "Socket file to use for connection",
(uchar **) &opt_unix_socket, (uchar **) &opt_unix_socket, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......
......@@ -43,7 +43,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if ((flags & VIO_BUFFERED_READ) &&
!(vio->read_buffer= (char*)my_malloc(VIO_READ_BUFFER_SIZE, MYF(MY_WME))))
flags&= ~VIO_BUFFERED_READ;
#ifdef __WIN__
#ifdef _WIN32
if (type == VIO_TYPE_NAMEDPIPE)
{
vio->viodelete =vio_delete;
......@@ -59,9 +59,16 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ignore_timeout;
vio->timeout=vio_win32_timeout;
/* Set default timeout */
vio->read_timeout_millis = INFINITE;
vio->write_timeout_millis = INFINITE;
memset(&(vio->pipe_overlapped), 0, sizeof(OVERLAPPED));
vio->pipe_overlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
DBUG_VOID_RETURN;
}
else /* default is VIO_TYPE_TCPIP */
#endif
#ifdef HAVE_SMEM
if (type == VIO_TYPE_SHARED_MEMORY)
......@@ -79,9 +86,14 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ignore_timeout;
/* Currently, shared memory is on Windows only, hence the below is ok*/
vio->timeout= vio_win32_timeout;
/* Set default timeout */
vio->read_timeout_millis= INFINITE;
vio->write_timeout_millis= INFINITE;
DBUG_VOID_RETURN;
}
else
#endif
#ifdef HAVE_OPENSSL
if (type == VIO_TYPE_SSL)
......@@ -100,8 +112,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking;
vio->timeout =vio_timeout;
DBUG_VOID_RETURN;
}
else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */
{
vio->viodelete =vio_delete;
......@@ -193,7 +205,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
}
#ifdef HAVE_SMEM
Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
HANDLE event_server_wrote, HANDLE event_server_read,
HANDLE event_client_wrote, HANDLE event_client_read,
HANDLE event_conn_closed)
......@@ -212,7 +224,6 @@ Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_m
vio->event_conn_closed= event_conn_closed;
vio->shared_memory_remain= 0;
vio->shared_memory_pos= handle_map;
vio->net= net;
strmov(vio->desc, "shared memory");
}
DBUG_RETURN(vio);
......
......@@ -22,7 +22,10 @@
#include <m_string.h>
#include <violite.h>
void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
#ifdef _WIN32
void vio_win32_timeout(Vio *vio, uint which, uint timeout);
#endif
void vio_timeout(Vio *vio,uint which, uint timeout);
#ifdef HAVE_OPENSSL
......
......@@ -261,19 +261,13 @@ int vio_close(Vio * vio)
{
int r=0;
DBUG_ENTER("vio_close");
#ifdef __WIN__
if (vio->type == VIO_TYPE_NAMEDPIPE)
{
#if defined(__NT__) && defined(MYSQL_SERVER)
CancelIo(vio->hPipe);
DisconnectNamedPipe(vio->hPipe);
#endif
r=CloseHandle(vio->hPipe);
}
else
#endif /* __WIN__ */
if (vio->type != VIO_CLOSED)
{
DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP ||
vio->type == VIO_TYPE_SOCKET ||
vio->type == VIO_TYPE_SSL);
DBUG_ASSERT(vio->sd >= 0);
if (shutdown(vio->sd, SHUT_RDWR))
r= -1;
......@@ -417,44 +411,97 @@ void vio_timeout(Vio *vio, uint which, uint timeout)
#ifdef __WIN__
size_t vio_read_pipe(Vio * vio, uchar* buf, size_t size)
/*
Finish pending IO on pipe. Honor wait timeout
*/
static int pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_millis)
{
DWORD length;
DWORD ret;
DBUG_ENTER("pipe_complete_io");
ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_millis);
/*
WaitForSingleObjects will normally return WAIT_OBJECT_O (success, IO completed)
or WAIT_TIMEOUT.
*/
if(ret != WAIT_OBJECT_0)
{
CancelIo(vio->hPipe);
DBUG_PRINT("error",("WaitForSingleObject() returned %d", ret));
DBUG_RETURN(-1);
}
if (!GetOverlappedResult(vio->hPipe,&(vio->pipe_overlapped),&length, FALSE))
{
DBUG_PRINT("error",("GetOverlappedResult() returned last error %d",
GetLastError()));
DBUG_RETURN(-1);
}
DBUG_RETURN(length);
}
size_t vio_read_pipe(Vio * vio, uchar *buf, size_t size)
{
DWORD bytes_read;
DBUG_ENTER("vio_read_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
DBUG_RETURN(-1);
if (!ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
&(vio->pipe_overlapped)))
{
if (GetLastError() != ERROR_IO_PENDING)
{
DBUG_PRINT("error",("ReadFile() returned last error %d",
GetLastError()));
DBUG_RETURN((size_t)-1);
}
bytes_read= pipe_complete_io(vio, buf, size,vio->read_timeout_millis);
}
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN((size_t) length);
DBUG_PRINT("exit", ("%d", bytes_read));
DBUG_RETURN(bytes_read);
}
size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
{
DWORD length;
DWORD bytes_written;
DBUG_ENTER("vio_write_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
DBUG_RETURN(-1);
if (!WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
&(vio->pipe_overlapped)))
{
if (GetLastError() != ERROR_IO_PENDING)
{
DBUG_PRINT("vio_error",("WriteFile() returned last error %d",
GetLastError()));
DBUG_RETURN((size_t)-1);
}
bytes_written = pipe_complete_io(vio, (char *)buf, size,
vio->write_timeout_millis);
}
DBUG_PRINT("exit", ("%d", length));
DBUG_RETURN((size_t) length);
DBUG_PRINT("exit", ("%d", bytes_written));
DBUG_RETURN(bytes_written);
}
int vio_close_pipe(Vio * vio)
{
int r;
DBUG_ENTER("vio_close_pipe");
#if defined(__NT__) && defined(MYSQL_SERVER)
CancelIo(vio->hPipe);
CloseHandle(vio->pipe_overlapped.hEvent);
DisconnectNamedPipe(vio->hPipe);
#endif
r=CloseHandle(vio->hPipe);
r= CloseHandle(vio->hPipe);
if (r)
{
DBUG_PRINT("vio_error", ("close() failed, error: %d",GetLastError()));
......@@ -466,10 +513,23 @@ int vio_close_pipe(Vio * vio)
}
void vio_ignore_timeout(Vio *vio __attribute__((unused)),
uint which __attribute__((unused)),
uint timeout __attribute__((unused)))
void vio_win32_timeout(Vio *vio, uint which , uint timeout_sec)
{
DWORD timeout_millis;
/*
Windows is measuring timeouts in milliseconds. Check for possible int
overflow.
*/
if (timeout_sec > UINT_MAX/1000)
timeout_millis= INFINITE;
else
timeout_millis= timeout_sec * 1000;
/* which == 1 means "write", which == 0 means "read".*/
if(which)
vio->write_timeout_millis= timeout_millis;
else
vio->read_timeout_millis= timeout_millis;
}
......@@ -504,7 +564,7 @@ size_t vio_read_shared_memory(Vio * vio, uchar* buf, size_t size)
WAIT_ABANDONED_0 and WAIT_TIMEOUT - fail. We can't read anything
*/
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
vio->net->read_timeout*1000) != WAIT_OBJECT_0)
vio->read_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
......@@ -561,7 +621,7 @@ size_t vio_write_shared_memory(Vio * vio, const uchar* buf, size_t size)
while (remain != 0)
{
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
vio->net->write_timeout*1000) != WAIT_OBJECT_0)
vio->write_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN((size_t) -1);
}
......
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