# At a local mysql-trunk-bugfixing repository of davi
3158 Davi Arnaut 2010-07-28
Bug#54790: Use of non-blocking mode for sockets limits performance
A pre-requisite patch for unifying the handling of socket timeouts.
This patch removes alarm based timeouts from the network layer
and transitions the code to a pure socket based timeout approach.
The handling of network I/O errors is split and documented, the
server and client libraries have different approaches to treating
interruptions.
Also, the low level packet reading loop is unrolled into two specific
sequences: reading the packet header and the payload. This make
error handling easier down the road.
@ include/my_global.h
A socket timeout is signalled with EAGAIN/EWOULDBLOCK. See socket(7).
@ sql/net_serv.cc
Remove the use of signal based alarms for timeouts. Instead, rely
on socket timeouts and blocking I/O. The error handling is changed
to recognize EAGAIN/EWOULDBLOCK as a timeout and EINTR as a forced
interruption depending on how the server was built.
Furthermore, the loop in the packet reading path (my_real_path) is
unrolled into two steps: reading the packet header and payload.
Each step is now documented and should be easier to understand.
@ vio/viosocket.c
In some cases, I/O operations should only be retried on EINTR.
Socket timeout is indicated with SOCKET_ETIMEDOUT. Method should
be renamed to not cause confusion with other types of interruption.
modified:
include/my_global.h
sql/net_serv.cc
vio/viosocket.c
=== modified file 'include/my_global.h'
--- a/include/my_global.h 2010-07-23 20:18:36 +0000
+++ b/include/my_global.h 2010-07-28 18:17:27 +0000
@@ -977,7 +977,7 @@ typedef ulong nesting_map; /* Used for
#define closesocket(A) close(A)
#define SOCKET_EINTR EINTR
#define SOCKET_EAGAIN EAGAIN
-#define SOCKET_ETIMEDOUT SOCKET_EINTR
+#define SOCKET_ETIMEDOUT SOCKET_EAGAIN
#define SOCKET_EWOULDBLOCK EWOULDBLOCK
#define SOCKET_EADDRINUSE EADDRINUSE
#define SOCKET_ENFILE ENFILE
=== modified file 'sql/net_serv.cc'
--- a/sql/net_serv.cc 2010-07-15 11:13:30 +0000
+++ b/sql/net_serv.cc 2010-07-28 18:17:27 +0000
@@ -61,29 +61,12 @@
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"
-void sql_print_error(const char *format,...);
-#else
-#define DONT_USE_THR_ALARM
-#endif /* NO_ALARM */
-
-#include "thr_alarm.h"
-
#ifdef MYSQL_SERVER
/*
The following variables/functions should really not be declared
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;
#ifndef MYSQL_INSTANCE_MANAGER
#ifdef HAVE_QUERY_CACHE
@@ -100,7 +83,6 @@ extern void query_cache_insert(const cha
#define thd_increment_bytes_sent(N)
#endif
-#define TEST_BLOCKING 8
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
@@ -133,13 +115,6 @@ my_bool my_net_init(NET *net, Vio* vio)
if (vio != 0) /* If real connection */
{
net->fd = vio_fd(vio); /* For perl DBI/DBD */
-#if defined(MYSQL_SERVER) && !defined(__WIN__)
- if (!(test_flags & TEST_BLOCKING))
- {
- my_bool old_mode;
- vio_blocking(vio, FALSE, &old_mode);
- }
-#endif
vio_fastsend(vio);
}
DBUG_RETURN(0);
@@ -180,7 +155,7 @@ my_bool net_realloc(NET *net, size_t len
/*
We must allocate some extra bytes for the end 0 and to be able to
read big compressed blocks + 1 safety byte since uint3korr() in
- my_real_read() may actually read 4 bytes depending on build flags and
+ net_read_packet() may actually read 4 bytes depending on build flags and
platform.
*/
if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
@@ -345,6 +320,48 @@ my_bool net_flush(NET *net)
}
+#if defined(MYSQL_SERVER) && !defined(DONT_USE_THR_ALARM)
+
+/**
+ In the server, I/O operations are not retried if thread alarm is being
+ used (DONT_USE_THR_ALARM is not defined). In this scenario, pthread_kill
+ is used to wake up (interrupt) threads waiting for I/O.
+*/
+static my_bool net_should_retry(NET *, uint *)
+{
+ return FALSE;
+}
+
+#elif !defined(MYSQL_SERVER) && defined(THREAD_SAFE_CLIENT)
+
+/**
+ In the thread safe client library, I/O operations are always retried
+ after a interrupted I/O operation. Otherwise, its either a timeout or
+ a unrecoverable error.
+*/
+static my_bool net_should_retry(NET *net, uint *)
+{
+ return vio_should_retry(net->vio);
+}
+
+#else
+
+/**
+ In the non-thread safe client library, or in the server without thread
+ alarm, I/O operations are retried up to a limit after a interrupted I/O
+ operation.
+*/
+static my_bool net_should_retry(NET *net, uint *retry_count)
+{
+ if (vio_should_retry(net->vio) && (*retry_count)++ < net->retry_count)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#endif
+
+
/*****************************************************************************
** Write something to server/client buffer
*****************************************************************************/
@@ -569,12 +586,7 @@ net_real_write(NET *net,const uchar *pac
{
size_t length;
const uchar *pos,*end;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
uint retry_count=0;
- my_bool net_blocking = vio_is_blocking(net->vio);
DBUG_ENTER("net_real_write");
#if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
@@ -616,14 +628,7 @@ net_real_write(NET *net,const uchar *pac
DBUG_DUMP("data", packet, len);
#endif
-#ifndef NO_ALARM
- thr_alarm_init(&alarmed);
- if (net_blocking)
- thr_alarm(&alarmed, net->write_timeout, &alarm_buff);
-#else
- alarmed=0;
- /* Write timeout is set in my_net_set_write_timeout */
-#endif /* NO_ALARM */
+ DBUG_ASSERT(vio_is_blocking(net->vio));
pos= packet;
end=pos+len;
@@ -631,55 +636,11 @@ net_real_write(NET *net,const uchar *pac
{
if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
{
- my_bool interrupted = vio_should_retry(net->vio);
-#if !defined(__WIN__)
- if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff))
- { /* Always true for client */
- my_bool old_mode;
- while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
- {
- if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
- continue;
-#ifdef 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
- goto end;
- }
- retry_count=0;
- continue;
- }
- }
- else
-#endif /* !defined(__WIN__) */
- if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
- interrupted)
- {
- if (retry_count++ < net->retry_count)
- continue;
-#ifdef EXTRA_DEBUG
- fprintf(stderr, "%s: write looped, aborting thread\n",
- my_progname);
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_errno(net->vio) == SOCKET_EINTR)
- {
- DBUG_PRINT("warning",("Interrupted write. Retrying..."));
- continue;
- }
-#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
+ if (net_should_retry(net, &retry_count))
+ continue;
net->error= 2; /* Close socket */
- net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
- ER_NET_ERROR_ON_WRITE);
+ net->last_errno= vio_was_interrupted(net->vio) ?
+ ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE;
#ifdef MYSQL_SERVER
my_error(net->last_errno, MYF(0));
#endif /* MYSQL_SERVER */
@@ -688,313 +649,202 @@ net_real_write(NET *net,const uchar *pac
pos+=length;
update_statistics(thd_increment_bytes_sent(length));
}
-#ifndef __WIN__
- end:
-#endif
#ifdef HAVE_COMPRESS
if (net->compress)
my_free((void*) packet);
#endif
- if (thr_alarm_in_use(&alarmed))
- {
- my_bool old_mode;
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking, &old_mode);
- }
net->reading_or_writing=0;
DBUG_RETURN(((int) (pos != end)));
}
+#define MY_VIO_SOCKET_ERROR ((size_t) -1)
-/*****************************************************************************
-** Read something from server/clinet
-*****************************************************************************/
+/**
+ Read a determined number of bytes from a network handler.
-#ifndef NO_ALARM
+ @param net NET handler.
+ @param count The number of bytes to read.
-static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
- thr_alarm_t *alarmed)
+ @return TRUE on error, FALSE on success.
+*/
+static my_bool net_read_raw_loop(NET *net, size_t count)
{
- uint retry_count=0;
- while (length > 0)
+ size_t recvcnt;
+ unsigned int retry_count= 0;
+ uchar *buf= net->buff + net->where_b;
+
+ DBUG_ASSERT(vio_is_blocking(net->vio));
+
+ while (count)
{
- size_t tmp;
- if ((long) (tmp= vio_read(net->vio, buff, length)) <= 0)
+ recvcnt= vio_read(net->vio, buf, count);
+
+ /* NET_SOCKET_ERROR (-1) indicates an error. */
+ if (recvcnt == MY_VIO_SOCKET_ERROR)
{
- my_bool interrupted = vio_should_retry(net->vio);
- if (!thr_got_alarm(alarmed) && interrupted)
- { /* Probably in MIT threads */
- if (retry_count++ < net->retry_count)
- continue;
- }
- return 1;
+ /* A recoverable I/O error occurred? */
+ if (net_should_retry(net, &retry_count))
+ continue;
+ else
+ break;
}
- length-= tmp;
- buff+= tmp;
+ /* Zero indicates end of file. */
+ else if (!recvcnt)
+ break;
+
+ count-= recvcnt;
+ buf+= recvcnt;
+ update_statistics(thd_increment_bytes_received(recvcnt));
}
- return 0;
+
+ /* On failure, propagate the error code. */
+ if (count)
+ {
+ /* Socket should be closed. */
+ net->error= 2;
+
+ /* Interrupted by a timeout/kill? */
+ if (recvcnt && vio_was_interrupted(net->vio))
+ net->last_errno= ER_NET_READ_INTERRUPTED;
+ else
+ net->last_errno= ER_NET_READ_ERROR;
+
+#ifdef MYSQL_SERVER
+ my_error(net->last_errno, MYF(0));
+#endif
+ }
+
+ return test(count);
}
+
+/*****************************************************************************
+** Read something from server/clinet
+*****************************************************************************/
+
+
/**
- Help function to clear the commuication buffer when we get a too big packet.
+ Read the header of a packet. The MySQL protocol packet header
+ consists of the length, in bytes, of the payload (packet data)
+ and a serial number.
- @param net Communication handle
- @param remain Bytes to read
- @param alarmed Parameter for thr_alarm()
- @param alarm_buff Parameter for thr_alarm()
+ @remark The encoded length is the length of the packet payload,
+ which does not include the packet header.
- @retval
- 0 Was able to read the whole packet
- @retval
- 1 Got mailformed packet from client
-*/
+ @remark The serial number is used to ensure that the packets are
+ received in order. If the packet serial number does not
+ match the expected value, a error is returned.
+
+ @param net NET handler.
-static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
- ALARM *alarm_buff)
+ @return TRUE on error, FALSE on success.
+*/
+static my_bool net_read_packet_header(NET *net)
{
- uint32 old=remain;
- DBUG_ENTER("my_net_skip_rest");
- DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
+ uchar pkt_nr;
+ size_t count= NET_HEADER_SIZE;
- /* The following is good for debugging */
- update_statistics(thd_increment_net_big_packet_count(1));
+ if (net->compress)
+ count+= COMP_HEADER_SIZE;
- if (!thr_alarm_in_use(alarmed))
- {
- my_bool old_mode;
- if (thr_alarm(alarmed,net->read_timeout, alarm_buff) ||
- vio_blocking(net->vio, TRUE, &old_mode) < 0)
- DBUG_RETURN(1); /* Can't setup, abort */
- }
- for (;;)
+ if (net_read_raw_loop(net, count))
+ return TRUE;
+
+ DBUG_DUMP("packet_header", net->buff + net->where_b, NET_HEADER_SIZE);
+
+ pkt_nr= net->buff[net->where_b + 3];
+
+ /*
+ Verify packet serial number against the truncated packet counter.
+ The local packet counter must be truncated since its not reset.
+ */
+ if (pkt_nr != (uchar) net->pkt_nr)
{
- while (remain > 0)
- {
- size_t length= min(remain, net->max_packet);
- if (net_safe_read(net, net->buff, length, alarmed))
- DBUG_RETURN(1);
- update_statistics(thd_increment_bytes_received(length));
- remain -= (uint32) length;
- }
- if (old != MAX_PACKET_LENGTH)
- break;
- if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
- DBUG_RETURN(1);
- old=remain= uint3korr(net->buff);
- net->pkt_nr++;
+ /* Not a NET error on the client. XXX: why? */
+#if defined(MYSQL_SERVER)
+ my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
+#elif defined(EXTRA_DEBUG)
+ fprintf(stderr, "Error: packets out of order (found %u, expected %u)\n",
+ (uint) pkt_nr, net->pkt_nr);
+ DBUG_ASSERT(pkt_nr == net->pkt_nr);
+#endif
}
- DBUG_RETURN(0);
+
+ net->pkt_nr++;
+
+ return FALSE;
}
-#endif /* NO_ALARM */
/**
- Reads one packet to net->buff + net->where_b.
- Long packets are handled by my_net_read().
- This function reallocates the net->buff buffer if necessary.
+ Read one (variable-length) MySQL protocol packet.
+ A MySQL packet consists of a header and a payload.
- @return
- Returns length of packet.
-*/
+ @remark Reads one packet to net->buff + net->where_b.
+ @remark Long packets are handled by my_net_read().
+ @remark The network buffer is expanded if necessary.
-static ulong
-my_real_read(NET *net, size_t *complen)
+ @return The length of the packet, or @packet_error on error.
+*/
+static ulong net_read_packet(NET *net, size_t *complen)
{
- uchar *pos;
- size_t length;
- uint i,retry_count=0;
- ulong len=packet_error;
- thr_alarm_t alarmed;
-#ifndef NO_ALARM
- ALARM alarm_buff;
-#endif
- my_bool net_blocking=vio_is_blocking(net->vio);
- uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
- NET_HEADER_SIZE);
- *complen = 0;
-
- net->reading_or_writing=1;
- thr_alarm_init(&alarmed);
-#ifndef NO_ALARM
- if (net_blocking)
- thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
-#else
- /* Read timeout is set in my_net_set_read_timeout */
-#endif /* NO_ALARM */
+ size_t pkt_len, pkt_data_len;
- pos = net->buff + net->where_b; /* net->packet -4 */
- for (i=0 ; i < 2 ; i++)
- {
- while (remain > 0)
- {
- /* First read is done with non blocking mode */
- if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
- {
- my_bool interrupted = vio_should_retry(net->vio);
-
- DBUG_PRINT("info",("vio_read returned %ld errno: %d",
- (long) length, vio_errno(net->vio)));
-#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
- mode and try again
- */
- if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
- {
- if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
- {
- my_bool old_mode;
- while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
- {
- if (vio_should_retry(net->vio) &&
- retry_count++ < net->retry_count)
- continue;
- DBUG_PRINT("error",
- ("fcntl returned error %d, aborting thread",
- vio_errno(net->vio)));
-#ifdef 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
- goto end;
- }
- retry_count=0;
- continue;
- }
- }
-#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",
- my_progname,vio_errno(net->vio));
-#endif /* EXTRA_DEBUG */
- }
-#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_errno(net->vio) == SOCKET_EINTR)
- {
- DBUG_PRINT("warning",("Interrupted read. Retrying..."));
- continue;
- }
-#endif
- DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld",
- remain, vio_errno(net->vio), (long) length));
- len= packet_error;
- net->error= 2; /* Close socket */
- 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
- goto end;
- }
- remain -= (uint32) length;
- pos+= length;
- update_statistics(thd_increment_bytes_received(length));
- }
- if (i == 0)
- { /* First parts is packet length */
- ulong helping;
- DBUG_DUMP("packet_header", net->buff+net->where_b,
- NET_HEADER_SIZE);
- if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
- {
- if (net->buff[net->where_b] != (uchar) 255)
- {
- DBUG_PRINT("error",
- ("Packets out of order (Found: %d, expected %u)",
- (int) net->buff[net->where_b + 3],
- net->pkt_nr));
- /*
- We don't make noise server side, since the client is expected
- to break the protocol for e.g. --send LOAD DATA .. LOCAL where
- 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",
- (int) net->buff[net->where_b + 3],
- (uint) (uchar) net->pkt_nr);
- fflush(stderr);
- DBUG_ASSERT(0);
-#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
- goto end;
- }
- net->compress_pkt_nr= ++net->pkt_nr;
-#ifdef HAVE_COMPRESS
- if (net->compress)
- {
- /*
- The following uint3korr() may read 4 bytes, so make sure we don't
- read unallocated or uninitialized memory. The right-hand expression
- must match the size of the buffer allocated in net_realloc().
- */
- DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <=
- net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1);
- /*
- If the packet is compressed then complen > 0 and contains the
- number of bytes in the uncompressed packet
- */
- *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
- }
-#endif
+ *complen= 0;
- len=uint3korr(net->buff+net->where_b);
- if (!len) /* End of big multi-packet */
- goto end;
- helping = max(len,*complen) + net->where_b;
- /* The necessary size of net->buff */
- if (helping >= net->max_packet)
- {
- if (net_realloc(net,helping))
- {
-#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
- if (!net->compress &&
- net->skip_big_packet &&
- !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
- net->error= 3; /* Successfully skiped packet */
-#endif
- len= packet_error; /* Return error and close connection */
- goto end;
- }
- }
- pos=net->buff + net->where_b;
- remain = (uint32) len;
- }
- }
+ net->reading_or_writing= TRUE;
-end:
- if (thr_alarm_in_use(&alarmed))
+ DBUG_ASSERT(vio_is_blocking(net->vio));
+
+ /* Retrieve packet length and number. */
+ if (net_read_packet_header(net))
+ goto error;
+
+#ifdef HAVE_COMPRESS
+ if (net->compress)
{
- my_bool old_mode;
- thr_end_alarm(&alarmed);
- vio_blocking(net->vio, net_blocking, &old_mode);
+ net->compress_pkt_nr= net->pkt_nr;
+
+ /*
+ The following uint3korr() may read 4 bytes, so make sure we don't
+ read unallocated or uninitialized memory. The right-hand expression
+ must match the size of the buffer allocated in net_realloc().
+ */
+ DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <=
+ net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1);
+
+ /*
+ If the packet is compressed then complen > 0 and contains the
+ number of bytes in the uncompressed packet.
+ */
+ *complen= uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
}
- net->reading_or_writing=0;
-#ifdef DEBUG_DATA_PACKETS
- if (len != packet_error)
- DBUG_DUMP("data", net->buff+net->where_b, len);
#endif
- return(len);
+
+ /* The length of the packet that follows. */
+ pkt_len= uint3korr(net->buff+net->where_b);
+
+ /* End of big multi-packet. */
+ if (!pkt_len)
+ goto end;
+
+ pkt_data_len = max(pkt_len, *complen) + net->where_b;
+
+ /* Expand packet buffer if necessary. */
+ if ((pkt_data_len >= net->max_packet) && net_realloc(net, pkt_data_len))
+ goto error;
+
+ /* Read the packet data (payload). */
+ if (net_read_raw_loop(net, pkt_len))
+ goto error;
+
+end:
+ net->reading_or_writing= FALSE;
+ return pkt_len;
+
+error:
+ net->reading_or_writing= FALSE;
+ return packet_error;
}
@@ -1025,7 +875,7 @@ my_net_read(NET *net)
if (!net->compress)
{
#endif
- len = my_real_read(net,&complen);
+ len= net_read_packet(net, &complen);
if (len == MAX_PACKET_LENGTH)
{
/* First packet of a multi-packet. Concatenate the packets */
@@ -1035,7 +885,7 @@ my_net_read(NET *net)
{
net->where_b += len;
total_length += len;
- len = my_real_read(net,&complen);
+ len= net_read_packet(net, &complen);
} while (len == MAX_PACKET_LENGTH);
if (len != packet_error)
len+= total_length;
@@ -1127,7 +977,7 @@ my_net_read(NET *net)
}
net->where_b=buf_length;
- if ((packet_len = my_real_read(net,&complen)) == packet_error)
+ if ((packet_len= net_read_packet(net, &complen)) == packet_error)
{
MYSQL_NET_READ_DONE(1, 0);
return packet_error;
@@ -1165,10 +1015,8 @@ void my_net_set_read_timeout(NET *net, u
DBUG_ENTER("my_net_set_read_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->read_timeout= timeout;
-#ifdef NO_ALARM
if (net->vio)
vio_timeout(net->vio, 0, timeout);
-#endif
DBUG_VOID_RETURN;
}
@@ -1178,9 +1026,7 @@ void my_net_set_write_timeout(NET *net,
DBUG_ENTER("my_net_set_write_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->write_timeout= timeout;
-#ifdef NO_ALARM
if (net->vio)
vio_timeout(net->vio, 1, timeout);
-#endif
DBUG_VOID_RETURN;
}
=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c 2010-05-21 13:17:01 +0000
+++ b/vio/viosocket.c 2010-07-28 18:17:27 +0000
@@ -240,29 +240,16 @@ int vio_keepalive(Vio* vio, my_bool set_
my_bool
-vio_should_retry(Vio * vio)
+vio_should_retry(Vio *vio __attribute__((unused)))
{
- int en = socket_errno;
- /*
- man 2 read write
- EAGAIN or EWOULDBLOCK when a socket is a non-blocking mode means
- that the read/write would block.
- man 7 socket
- EAGAIN or EWOULDBLOCK when a socket is in a blocking mode means
- that the corresponding receiving or sending timeout was reached.
- */
- return en == SOCKET_EINTR ||
- (!vio_is_blocking(vio) &&
- (en == SOCKET_EAGAIN || en == SOCKET_EWOULDBLOCK));
+ return (socket_errno == SOCKET_EINTR);
}
my_bool
vio_was_interrupted(Vio *vio __attribute__((unused)))
{
- int en= socket_errno;
- return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
- en == SOCKET_EWOULDBLOCK || en == SOCKET_ETIMEDOUT);
+ return (socket_errno == SOCKET_ETIMEDOUT);
}
Attachment: [text/bzr-bundle] bzr/davi.arnaut@oracle.com-20100728181727-gatfi0p243koals7.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-bugfixing branch (davi:3158) Bug#54790 | Davi Arnaut | 28 Jul |