summaryrefslogtreecommitdiff
path: root/sql/net_serv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/net_serv.cc')
-rw-r--r--sql/net_serv.cc167
1 files changed, 91 insertions, 76 deletions
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index df392616676..08ac93f3091 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2012, Monty Program 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
@@ -35,7 +36,6 @@
*/
#include <my_global.h>
#include <mysql.h>
-#include <mysql_embed.h>
#include <mysql_com.h>
#include <mysqld_error.h>
#include <my_sys.h>
@@ -44,9 +44,7 @@
#include <violite.h>
#include <signal.h>
#include <errno.h>
-#ifdef __NETWARE__
-#include <sys/select.h>
-#endif
+#include "probes_mysql.h"
#ifdef EMBEDDED_LIBRARY
#undef MYSQL_SERVER
@@ -54,20 +52,38 @@
#define MYSQL_CLIENT
#endif /*EMBEDDED_LIBRARY */
+/*
+ to reduce the number of ifdef's in the code
+*/
+#ifdef EXTRA_DEBUG
+#define EXTRA_DEBUG_fprintf fprintf
+#define EXTRA_DEBUG_fflush fflush
+#else
+static void inline EXTRA_DEBUG_fprintf(...) {}
+static int inline EXTRA_DEBUG_fflush(...) { return 0; }
+#endif
+#ifdef MYSQL_SERVER
+#define MYSQL_SERVER_my_error my_error
+#else
+static void inline MYSQL_SERVER_my_error(...) {}
+#endif
+
/*
The following handles the differences when this is linked between the
client and the server.
- This gives an error if a too big packet is found
- The server can change this with the -O switch, but because the client
- can't normally do this the client should have a bigger max_allowed_packet.
+ This gives an error if a too big packet is found.
+ The server can change this, but because the client can't normally do this
+ the client should have a bigger max_allowed_packet.
*/
#if defined(__WIN__) || !defined(MYSQL_SERVER)
/* The following is because alarms doesn't work on windows. */
+#ifndef NO_ALARM
#define NO_ALARM
#endif
+#endif
#ifndef NO_ALARM
#include "my_pthread.h"
@@ -81,25 +97,19 @@ void sql_print_error(const char *format,...);
#ifdef MYSQL_SERVER
/*
The following variables/functions should really not be declared
- extern, but as it's hard to include mysql_priv.h here, we have to
+ extern, but as it's hard to include sql_priv.h here, we have to
live with this for a while.
*/
extern uint test_flags;
extern ulong bytes_sent, bytes_received, net_big_packet_count;
-extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
-#ifndef MYSQL_INSTANCE_MANAGER
#ifdef HAVE_QUERY_CACHE
#define USE_QUERY_CACHE
-extern void query_cache_init_query(NET *net);
-extern void query_cache_insert(NET *net, const char *packet, ulong length);
+extern void query_cache_insert(const char *packet, ulong length,
+ unsigned pkt_nr);
#endif // HAVE_QUERY_CACHE
#define update_statistics(A) A
-#endif /* MYSQL_INSTANCE_MANGER */
-#endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */
-
-#if !defined(MYSQL_SERVER) || defined(MYSQL_INSTANCE_MANAGER)
+#else
#define update_statistics(A)
-#define thd_increment_bytes_sent(N)
#endif
#define TEST_BLOCKING 8
@@ -120,7 +130,7 @@ my_bool my_net_init(NET *net, Vio* vio)
MYF(MY_WME))))
DBUG_RETURN(1);
net->buff_end=net->buff+net->max_packet;
- net->error=0; net->return_errno=0; net->return_status=0;
+ net->error=0; net->return_status=0;
net->pkt_nr=net->compress_pkt_nr=0;
net->write_pos=net->read_pos = net->buff;
net->last_error[0]=0;
@@ -128,11 +138,7 @@ my_bool my_net_init(NET *net, Vio* vio)
net->where_b = net->remain_in_buf=0;
net->net_skip_rest_factor= 0;
net->last_errno=0;
-#ifdef USE_QUERY_CACHE
- query_cache_init_query(net);
-#else
- net->query_cache_query= 0;
-#endif
+ net->unused= 0;
if (vio != 0) /* If real connection */
{
@@ -153,7 +159,7 @@ my_bool my_net_init(NET *net, Vio* vio)
void net_end(NET *net)
{
DBUG_ENTER("net_end");
- my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(net->buff);
net->buff=0;
DBUG_VOID_RETURN;
}
@@ -175,9 +181,7 @@ my_bool net_realloc(NET *net, size_t length)
/* @todo: 1 and 2 codes are identical. */
net->error= 1;
net->last_errno= ER_NET_PACKET_TOO_LARGE;
-#ifdef MYSQL_SERVER
- my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
DBUG_RETURN(1);
}
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
@@ -299,10 +303,8 @@ void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
DBUG_PRINT("info",("skipped %ld bytes from file: %s",
(long) count, vio_description(net->vio)));
-#if defined(EXTRA_DEBUG)
- fprintf(stderr,"Note: net_clear() skipped %ld bytes from file: %s\n",
+ EXTRA_DEBUG_fprintf(stderr,"Note: net_clear() skipped %ld bytes from file: %s\n",
(long) count, vio_description(net->vio));
-#endif
}
else
{
@@ -372,8 +374,13 @@ my_bool
my_net_write(NET *net,const uchar *packet,size_t len)
{
uchar buff[NET_HEADER_SIZE];
+ int rc;
+
if (unlikely(!net->vio)) /* nowhere to write */
return 0;
+
+ MYSQL_NET_WRITE_START(len);
+
/*
Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH
length. The last packet is always a packet that is < MAX_PACKET_LENGTH.
@@ -386,7 +393,10 @@ my_net_write(NET *net,const uchar *packet,size_t len)
buff[3]= (uchar) net->pkt_nr++;
if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
net_write_buff(net, packet, z_size))
+ {
+ MYSQL_NET_WRITE_DONE(1);
return 1;
+ }
packet += z_size;
len-= z_size;
}
@@ -394,11 +404,16 @@ my_net_write(NET *net,const uchar *packet,size_t len)
int3store(buff,len);
buff[3]= (uchar) net->pkt_nr++;
if (net_write_buff(net, buff, NET_HEADER_SIZE))
+ {
+ MYSQL_NET_WRITE_DONE(1);
return 1;
+ }
#ifndef DEBUG_DATA_PACKETS
DBUG_DUMP("packet_header", buff, NET_HEADER_SIZE);
#endif
- return test(net_write_buff(net,packet,len));
+ rc= test(net_write_buff(net,packet,len));
+ MYSQL_NET_WRITE_DONE(rc);
+ return rc;
}
/**
@@ -436,9 +451,12 @@ net_write_command(NET *net,uchar command,
size_t length=len+1+head_len; /* 1 extra byte for command */
uchar buff[NET_HEADER_SIZE+1];
uint header_size=NET_HEADER_SIZE+1;
+ int rc;
DBUG_ENTER("net_write_command");
DBUG_PRINT("enter",("length: %lu", (ulong) len));
+ MYSQL_NET_WRITE_START(length);
+
buff[4]=command; /* For first packet */
if (length >= MAX_PACKET_LENGTH)
@@ -452,7 +470,10 @@ net_write_command(NET *net,uchar command,
if (net_write_buff(net, buff, header_size) ||
net_write_buff(net, header, head_len) ||
net_write_buff(net, packet, len))
+ {
+ MYSQL_NET_WRITE_DONE(1);
DBUG_RETURN(1);
+ }
packet+= len;
length-= MAX_PACKET_LENGTH;
len= MAX_PACKET_LENGTH;
@@ -463,9 +484,11 @@ net_write_command(NET *net,uchar command,
}
int3store(buff,length);
buff[3]= (uchar) net->pkt_nr++;
- DBUG_RETURN(test(net_write_buff(net, buff, header_size) ||
- (head_len && net_write_buff(net, header, head_len)) ||
- net_write_buff(net, packet, len) || net_flush(net)));
+ rc= test(net_write_buff(net, buff, header_size) ||
+ (head_len && net_write_buff(net, header, head_len)) ||
+ net_write_buff(net, packet, len) || net_flush(net));
+ MYSQL_NET_WRITE_DONE(rc);
+ DBUG_RETURN(rc);
}
/**
@@ -566,7 +589,7 @@ net_real_write(NET *net,const uchar *packet, size_t len)
DBUG_ENTER("net_real_write");
#if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
- query_cache_insert(net, (char*) packet, len);
+ query_cache_insert((char*) packet, len, net->pkt_nr);
#endif
if (net->error == 2)
@@ -630,16 +653,12 @@ net_real_write(NET *net,const uchar *packet, size_t len)
{
if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
+ EXTRA_DEBUG_fprintf(stderr,
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
net->error= 2; /* Close socket */
net->last_errno= ER_NET_PACKET_TOO_LARGE;
-#ifdef MYSQL_SERVER
- my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
goto end;
}
retry_count=0;
@@ -653,24 +672,20 @@ net_real_write(NET *net,const uchar *packet, size_t len)
{
if (retry_count++ < net->retry_count)
continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: write looped, aborting thread\n",
+ EXTRA_DEBUG_fprintf(stderr, "%s: write looped, aborting thread\n",
my_progname);
-#endif /* EXTRA_DEBUG */
}
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
+#ifndef MYSQL_SERVER
if (vio_errno(net->vio) == SOCKET_EINTR)
{
DBUG_PRINT("warning",("Interrupted write. Retrying..."));
continue;
}
-#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
+#endif /* !defined(MYSQL_SERVER) */
net->error= 2; /* Close socket */
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
ER_NET_ERROR_ON_WRITE);
-#ifdef MYSQL_SERVER
- my_error(net->last_errno, MYF(0));
-#endif /* MYSQL_SERVER */
+ MYSQL_SERVER_my_error(net->last_errno, MYF(0));
break;
}
pos+=length;
@@ -681,7 +696,7 @@ net_real_write(NET *net,const uchar *packet, size_t len)
#endif
#ifdef HAVE_COMPRESS
if (net->compress)
- my_free((char*) packet,MYF(0));
+ my_free((void*) packet);
#endif
if (thr_alarm_in_use(&alarmed))
{
@@ -828,10 +843,10 @@ my_real_read(NET *net, size_t *complen)
DBUG_PRINT("info",("vio_read returned %ld errno: %d",
(long) length, vio_errno(net->vio)));
-#if !defined(__WIN__) || defined(MYSQL_SERVER)
+#if !defined(__WIN__) && defined(MYSQL_SERVER)
/*
We got an error that there was no data on the socket. We now set up
- an alarm to not 'read forever', change the socket to non blocking
+ an alarm to not 'read forever', change the socket to the blocking
mode and try again
*/
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
@@ -847,35 +862,29 @@ my_real_read(NET *net, size_t *complen)
DBUG_PRINT("error",
("fcntl returned error %d, aborting thread",
vio_errno(net->vio)));
-#ifdef EXTRA_DEBUG
- fprintf(stderr,
+ EXTRA_DEBUG_fprintf(stderr,
"%s: read: fcntl returned error %d, aborting thread\n",
my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
len= packet_error;
net->error= 2; /* Close socket */
net->last_errno= ER_NET_FCNTL_ERROR;
-#ifdef MYSQL_SERVER
- my_error(ER_NET_FCNTL_ERROR, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(ER_NET_FCNTL_ERROR, MYF(0));
goto end;
}
retry_count=0;
continue;
}
}
-#endif /* (!defined(__WIN__) || defined(MYSQL_SERVER) */
+#endif /* (!defined(__WIN__) && defined(MYSQL_SERVER) */
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
interrupted)
{ /* Probably in MIT threads */
if (retry_count++ < net->retry_count)
continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
+ EXTRA_DEBUG_fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
}
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
+#ifndef MYSQL_SERVER
if (vio_errno(net->vio) == SOCKET_EINTR)
{
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
@@ -889,9 +898,7 @@ my_real_read(NET *net, size_t *complen)
net->last_errno= (vio_was_interrupted(net->vio) ?
ER_NET_READ_INTERRUPTED :
ER_NET_READ_ERROR);
-#ifdef MYSQL_SERVER
- my_error(net->last_errno, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(net->last_errno, MYF(0));
goto end;
}
remain -= (uint32) length;
@@ -917,19 +924,17 @@ my_real_read(NET *net, size_t *complen)
the server expects the client to send a file, but the client
may reply with a new command instead.
*/
-#if defined (EXTRA_DEBUG) && !defined (MYSQL_SERVER)
- fflush(stdout);
- fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
+#ifndef MYSQL_SERVER
+ EXTRA_DEBUG_fflush(stdout);
+ EXTRA_DEBUG_fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
(int) net->buff[net->where_b + 3],
(uint) (uchar) net->pkt_nr);
- fflush(stderr);
+ EXTRA_DEBUG_fflush(stderr);
#endif
}
len= packet_error;
/* Not a NET error on the client. XXX: why? */
-#ifdef MYSQL_SERVER
- my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
goto end;
}
net->compress_pkt_nr= ++net->pkt_nr;
@@ -1012,6 +1017,8 @@ my_net_read(NET *net)
{
size_t len, complen;
+ MYSQL_NET_READ_START();
+
#ifdef HAVE_COMPRESS
if (!net->compress)
{
@@ -1035,6 +1042,7 @@ my_net_read(NET *net)
net->read_pos = net->buff + net->where_b;
if (len != packet_error)
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
+ MYSQL_NET_READ_DONE(0, len);
return len;
#ifdef HAVE_COMPRESS
}
@@ -1118,15 +1126,17 @@ my_net_read(NET *net)
net->where_b=buf_length;
if ((packet_len = my_real_read(net,&complen)) == packet_error)
+ {
+ MYSQL_NET_READ_DONE(1, 0);
return packet_error;
+ }
if (my_uncompress(net->buff + net->where_b, packet_len,
&complen))
{
net->error= 2; /* caller will close socket */
net->last_errno= ER_NET_UNCOMPRESS_ERROR;
-#ifdef MYSQL_SERVER
- my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
-#endif
+ MYSQL_SERVER_my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
+ MYSQL_NET_READ_DONE(1, 0);
return packet_error;
}
buf_length+= complen;
@@ -1141,6 +1151,7 @@ my_net_read(NET *net)
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
}
#endif /* HAVE_COMPRESS */
+ MYSQL_NET_READ_DONE(0, len);
return len;
}
@@ -1149,6 +1160,8 @@ void my_net_set_read_timeout(NET *net, uint timeout)
{
DBUG_ENTER("my_net_set_read_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
+ if (net->read_timeout == timeout)
+ DBUG_VOID_RETURN;
net->read_timeout= timeout;
#ifdef NO_ALARM
if (net->vio)
@@ -1162,6 +1175,8 @@ void my_net_set_write_timeout(NET *net, uint timeout)
{
DBUG_ENTER("my_net_set_write_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
+ if (net->write_timeout == timeout)
+ DBUG_VOID_RETURN;
net->write_timeout= timeout;
#ifdef NO_ALARM
if (net->vio)