diff options
-rwxr-xr-x | BUILD/SETUP.sh | 4 | ||||
-rw-r--r-- | BUILD/compile-pentium64-valgrind-max | 2 | ||||
-rw-r--r-- | config/ac-macros/misc.m4 | 23 | ||||
-rw-r--r-- | config/ac-macros/openssl.m4 | 3 | ||||
-rw-r--r-- | include/config-win.h | 2 | ||||
-rw-r--r-- | include/violite.h | 20 | ||||
-rw-r--r-- | sql-common/client.c | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | vio/vio.c | 45 | ||||
-rw-r--r-- | vio/viosocket.c | 46 |
10 files changed, 102 insertions, 50 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 403857f403f..fbb0936c4b5 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -48,8 +48,8 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" -base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-raid --with-openssl --with-raid --with-vio" -max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-raid --with-openssl --with-raid --with-vio --with-embedded-server" +base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-raid --with-openssl --with-raid" +max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-raid --with-openssl --with-raid --with-embedded-server" max_no_es_configs="$max_leave_isam_configs --without-isam" max_configs="$max_no_es_configs --with-embedded-server" diff --git a/BUILD/compile-pentium64-valgrind-max b/BUILD/compile-pentium64-valgrind-max index 7f78089c3e8..2e4ff8e0082 100644 --- a/BUILD/compile-pentium64-valgrind-max +++ b/BUILD/compile-pentium64-valgrind-max @@ -9,7 +9,7 @@ cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" # We want to test isam when building with valgrind -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-vio --with-raid --with-ndbcluster" +extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-raid --with-ndbcluster" . "$path/FINISH.sh" diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index ec0c296a8b2..556cc7625cc 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -594,22 +594,13 @@ AC_MSG_RESULT($ac_cv_conv_longlong_to_float) ]) AC_DEFUN([MYSQL_CHECK_VIO], [ - AC_ARG_WITH([vio], - [ --with-vio Include the Virtual IO support], - [vio="$withval"], - [vio=no]) - - if test "$vio" = "yes" - then - vio_dir="vio" - vio_libs="../vio/libvio.la" - AC_DEFINE(HAVE_VIO, 1) - else - vio_dir="" - vio_libs="" - fi - AC_SUBST([vio_dir]) - AC_SUBST([vio_libs]) +dnl +dnl we always use vio: no need for special defines +dnl + AC_DEFINE([HAVE_VIO_READ_BUFF], [1], + [Define to enable buffered read. This works only if syscalls + read/recv return as soon as there is some data in the kernel + buffer, no matter how big the given buffer is.]) ]) # Local version of _AC_PROG_CXX_EXIT_DECLARATION that does not diff --git a/config/ac-macros/openssl.m4 b/config/ac-macros/openssl.m4 index 9da0e38f2ba..6541a492247 100644 --- a/config/ac-macros/openssl.m4 +++ b/config/ac-macros/openssl.m4 @@ -89,9 +89,6 @@ AC_MSG_CHECKING(for OpenSSL) fi MYSQL_FIND_OPENSSL([$openssl_includes], [$openssl_libs]) #force VIO use - vio_dir="vio" - vio_libs="../vio/libvio.la" - AC_DEFINE([HAVE_VIO], [1], [Virtual IO]) AC_MSG_RESULT(yes) openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto" # Don't set openssl_includes to /usr/include as this gives us a lot of diff --git a/include/config-win.h b/include/config-win.h index e86e0f08596..4ef5c9323e7 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -308,7 +308,7 @@ inline double ulonglong2double(ulonglong value) #define HAVE_QUERY_CACHE #define SPRINTF_RETURNS_INT #define HAVE_SETFILEPOINTER -#define HAVE_VIO +#define HAVE_VIO_READ_BUFF #ifdef NOT_USED #define HAVE_SNPRINTF /* Gave link error */ diff --git a/include/violite.h b/include/violite.h index 855d8a3d490..a62fe37f45d 100644 --- a/include/violite.h +++ b/include/violite.h @@ -37,7 +37,12 @@ enum enum_vio_type VIO_TYPE_SSL, VIO_TYPE_SHARED_MEMORY }; -Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost); + +#define VIO_LOCALHOST 1 /* a localhost connection */ +#define VIO_BUFFERED_READ 2 /* use buffered read */ +#define VIO_READ_BUFFER_SIZE 16384 /* size of read buffer */ + +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, @@ -57,8 +62,9 @@ int vio_close_pipe(Vio * vio); void vio_delete(Vio* vio); int vio_close(Vio* vio); void vio_reset(Vio* vio, enum enum_vio_type type, - my_socket sd, HANDLE hPipe, my_bool localhost); + my_socket sd, HANDLE hPipe, uint flags); int vio_read(Vio *vio, gptr buf, int size); +int vio_read_buff(Vio *vio, gptr buf, int size); int vio_write(Vio *vio, const gptr buf, int size); int vio_blocking(Vio *vio, my_bool onoff, my_bool *old_mode); my_bool vio_is_blocking(Vio *vio); @@ -135,7 +141,7 @@ int vio_close_shared_memory(Vio * vio); } #endif -#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO) +#if !defined(DONT_MAP_VIO) #define vio_delete(vio) (vio)->viodelete(vio) #define vio_errno(vio) (vio)->vioerrno(vio) #define vio_read(vio, buf, size) (vio)->read(vio,buf,size) @@ -150,7 +156,7 @@ int vio_close_shared_memory(Vio * vio); #define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt) #define vio_in_addr(vio, in) (vio)->in_addr(vio, in) #define vio_timeout(vio, seconds) (vio)->timeout(vio, seconds) -#endif /* defined(HAVE_VIO) && !defined(DONT_MAP_VIO) */ +#endif /* !defined(DONT_MAP_VIO) */ /* This enumerator is used in parser - should be always visible */ enum SSL_type @@ -175,7 +181,10 @@ struct st_vio struct sockaddr_in remote; /* Remote internet address */ enum enum_vio_type type; /* Type of connection */ char desc[30]; /* String description */ -#ifdef HAVE_VIO + char *read_buffer; /* buffer for vio_read_buff */ + char *read_pos; /* start of unfetched data in the + read buffer */ + char *read_end; /* end of unfetched data */ /* function pointers. They are similar for socket/SSL/whatever */ void (*viodelete)(Vio*); int (*vioerrno)(Vio*); @@ -203,6 +212,5 @@ struct st_vio char *shared_memory_pos; NET *net; #endif /* HAVE_SMEM */ -#endif /* HAVE_VIO */ }; #endif /* vio_violite_h_ */ diff --git a/sql-common/client.c b/sql-common/client.c index aece4230fe0..2c73cb4d07c 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1681,7 +1681,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, ER(net->last_errno),socket_errno); goto error; } - net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE); + net->vio= vio_new(sock, VIO_TYPE_SOCKET, + VIO_LOCALHOST | VIO_BUFFERED_READ); bzero((char*) &UNIXaddr,sizeof(UNIXaddr)); UNIXaddr.sun_family = AF_UNIX; strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1); @@ -1756,7 +1757,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, ER(net->last_errno),socket_errno); goto error; } - net->vio = vio_new(sock,VIO_TYPE_TCPIP,FALSE); + net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ); bzero((char*) &sock_addr,sizeof(sock_addr)); sock_addr.sin_family = AF_INET; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a4d6e59d5d6..a70f83b78b9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3745,7 +3745,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets, if (!(vio_tmp=vio_new(new_sock, sock == unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP, - sock == unix_sock)) || + sock == unix_sock ? VIO_LOCALHOST: 0)) || my_net_init(&thd->net,vio_tmp)) { if (vio_tmp) diff --git a/vio/vio.c b/vio/vio.c index ea254e2ed5a..6227493b994 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -27,20 +27,23 @@ * Helper to fill most of the Vio* with defaults. */ -void vio_reset(Vio* vio, enum enum_vio_type type, - my_socket sd, HANDLE hPipe, - my_bool localhost) +static void vio_init(Vio* vio, enum enum_vio_type type, + my_socket sd, HANDLE hPipe, uint flags) { - DBUG_ENTER("vio_reset"); - DBUG_PRINT("enter", ("type: %d sd: %d localhost: %d", type, sd, - localhost)); + DBUG_ENTER("vio_init"); + DBUG_PRINT("enter", ("type: %d sd: %d flags: %d", type, sd, flags)); +#ifndef HAVE_VIO_READ_BUFF + flags&= ~VIO_BUFFERED_READ; +#endif bzero((char*) vio, sizeof(*vio)); vio->type = type; vio->sd = sd; vio->hPipe = hPipe; - vio->localhost= localhost; -#ifdef HAVE_VIO + vio->localhost= flags & VIO_LOCALHOST; + if ((flags & VIO_BUFFERED_READ) && + !(vio->read_buffer= (char*)my_malloc(VIO_READ_BUFFER_SIZE, MYF(MY_WME)))) + flags&= ~VIO_BUFFERED_READ; #ifdef __WIN__ if (type == VIO_TYPE_NAMEDPIPE) { @@ -101,7 +104,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, { vio->viodelete =vio_delete; vio->vioerrno =vio_errno; - vio->read =vio_read; + vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read; vio->write =vio_write; vio->fastsend =vio_fastsend; vio->viokeepalive =vio_keepalive; @@ -113,21 +116,30 @@ void vio_reset(Vio* vio, enum enum_vio_type type, vio->is_blocking =vio_is_blocking; vio->timeout =vio_timeout; } -#endif /* HAVE_VIO */ DBUG_VOID_RETURN; } +/* Reset initialized VIO to use with another transport type */ + +void vio_reset(Vio* vio, enum enum_vio_type type, + my_socket sd, HANDLE hPipe, uint flags) +{ + my_free(vio->read_buffer, MYF(MY_ALLOW_ZERO_PTR)); + vio_init(vio, type, sd, hPipe, flags); +} + + /* Open the socket or TCP/IP connection and read the fnctl() status */ -Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) +Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags) { Vio *vio; DBUG_ENTER("vio_new"); DBUG_PRINT("enter", ("sd: %d", sd)); if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME)))) { - vio_reset(vio, type, sd, 0, localhost); + vio_init(vio, type, sd, 0, flags); sprintf(vio->desc, (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"), vio->sd); @@ -163,7 +175,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe) DBUG_ENTER("vio_new_handle"); if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME)))) { - vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE); + vio_init(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, VIO_LOCALHOST); strmov(vio->desc, "named pipe"); } DBUG_RETURN(vio); @@ -179,7 +191,7 @@ Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_m 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_init(vio, VIO_TYPE_SHARED_MEMORY, 0, 0, VIO_LOCALHOST); vio->handle_file_map= handle_file_map; vio->handle_map= handle_map; vio->event_server_wrote= event_server_wrote; @@ -204,11 +216,8 @@ void vio_delete(Vio* vio) if (vio) { if (vio->type != VIO_CLOSED) -#ifdef HAVE_VIO /*WAX*/ vio->vioclose(vio); -#else - vio_close(vio); -#endif + my_free((gptr) vio->read_buffer, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) vio,MYF(0)); } } diff --git a/vio/viosocket.c b/vio/viosocket.c index 43bd4e82013..ea85a69e2d4 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -35,6 +35,8 @@ int vio_read(Vio * vio, gptr buf, int size) DBUG_ENTER("vio_read"); DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + /* Ensure nobody uses vio_read_buff and vio_read simultaneously */ + DBUG_ASSERT(vio->read_end == vio->read_pos); #ifdef __WIN__ r = recv(vio->sd, buf, size,0); #else @@ -52,6 +54,50 @@ int vio_read(Vio * vio, gptr buf, int size) } +/* + Buffered read: if average read size is small it may + reduce number of syscalls. +*/ + +int vio_read_buff(Vio *vio, gptr buf, int size) +{ + int rc; +#define VIO_UNBUFFERED_READ_MIN_SIZE 2048 + DBUG_ENTER("vio_read_buff"); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + + if (vio->read_pos < vio->read_end) + { + rc= min(vio->read_end - vio->read_pos, size); + memcpy(buf, vio->read_pos, rc); + vio->read_pos+= rc; + /* + Do not try to read from the socket now even if rc < size: + vio_read can return -1 due to an error or non-blocking mode, and + the safest way to handle it is to move to a separate branch. + */ + } + else if (size < VIO_UNBUFFERED_READ_MIN_SIZE) + { + rc= vio_read(vio, vio->read_buffer, VIO_READ_BUFFER_SIZE); + if (rc > 0) + { + if (rc > size) + { + vio->read_pos= vio->read_buffer + size; + vio->read_end= vio->read_buffer + rc; + rc= size; + } + memcpy(buf, vio->read_buffer, rc); + } + } + else + rc= vio_read(vio, buf, size); + DBUG_RETURN(rc); +#undef VIO_UNBUFFERED_READ_MIN_SIZE +} + + int vio_write(Vio * vio, const gptr buf, int size) { int r; |