2012-08-14 16:23:34 +02:00
|
|
|
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
2012-02-28 18:53:05 +01:00
|
|
|
Copyright (c) 2012, Monty Program Ab
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2001-05-20 14:04:46 +02:00
|
|
|
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
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2001-05-20 14:04:46 +02:00
|
|
|
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.
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2001-05-20 14:04:46 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2019-05-11 20:29:06 +02:00
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
2001-05-20 14:04:46 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
Note that we can't have assertion on file descriptors; The reason for
|
|
|
|
this is that during mysql shutdown, another thread can close a file
|
|
|
|
we are working on. In this case we should just return read errors from
|
|
|
|
the file descriptior.
|
|
|
|
*/
|
|
|
|
|
2003-08-27 01:51:39 +02:00
|
|
|
#include "vio_priv.h"
|
2017-05-03 21:22:59 +02:00
|
|
|
#include "ssl_compat.h"
|
2001-05-20 14:04:46 +02:00
|
|
|
|
2020-01-29 13:50:26 +01:00
|
|
|
PSI_memory_key key_memory_vio_ssl_fd;
|
|
|
|
PSI_memory_key key_memory_vio;
|
|
|
|
PSI_memory_key key_memory_vio_read_buffer;
|
|
|
|
|
|
|
|
#ifdef HAVE_PSI_INTERFACE
|
|
|
|
static PSI_memory_info all_vio_memory[]=
|
|
|
|
{
|
|
|
|
{&key_memory_vio_ssl_fd, "ssl_fd", 0},
|
|
|
|
{&key_memory_vio, "vio", 0},
|
|
|
|
{&key_memory_vio_read_buffer, "read_buffer", 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
void init_vio_psi_keys()
|
|
|
|
{
|
|
|
|
const char* category= "vio";
|
|
|
|
int count;
|
|
|
|
|
|
|
|
count= array_elements(all_vio_memory);
|
|
|
|
mysql_memory_register(category, all_vio_memory, count);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
#ifdef _WIN32
|
2009-11-10 20:36:38 +01:00
|
|
|
|
|
|
|
/**
|
2012-08-14 16:23:34 +02:00
|
|
|
Stub io_wait method that defaults to indicate that
|
|
|
|
requested I/O event is ready.
|
2009-11-10 20:36:38 +01:00
|
|
|
|
|
|
|
Used for named pipe and shared memory VIO types.
|
|
|
|
|
|
|
|
@param vio Unused.
|
2012-08-14 16:23:34 +02:00
|
|
|
@param event Unused.
|
2009-11-10 20:36:38 +01:00
|
|
|
@param timeout Unused.
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
@retval 1 The requested I/O event has occurred.
|
2009-11-10 20:36:38 +01:00
|
|
|
*/
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
static int no_io_wait(Vio *vio __attribute__((unused)),
|
|
|
|
enum enum_vio_io_event event __attribute__((unused)),
|
|
|
|
int timeout __attribute__((unused)))
|
2009-11-10 20:36:38 +01:00
|
|
|
{
|
2012-08-14 16:23:34 +02:00
|
|
|
return 1;
|
2009-11-10 20:36:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-06-07 16:01:39 +02:00
|
|
|
static my_bool has_no_data(Vio *vio __attribute__((unused)))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2011-12-08 19:17:49 +01:00
|
|
|
#ifdef _WIN32
|
|
|
|
int vio_pipe_shutdown(Vio *vio, int how)
|
|
|
|
{
|
2020-08-03 13:23:38 +02:00
|
|
|
vio->shutdown_flag= how;
|
2016-06-01 13:29:40 +02:00
|
|
|
return CancelIoEx(vio->hPipe, NULL);
|
2011-12-08 19:17:49 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-05-20 14:04:46 +02:00
|
|
|
/*
|
2001-05-31 16:18:25 +02:00
|
|
|
* Helper to fill most of the Vio* with defaults.
|
2001-05-20 14:04:46 +02:00
|
|
|
*/
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
static void vio_init(Vio *vio, enum enum_vio_type type,
|
|
|
|
my_socket sd, uint flags)
|
2001-05-20 14:04:46 +02:00
|
|
|
{
|
2005-03-05 22:10:08 +01:00
|
|
|
DBUG_ENTER("vio_init");
|
2017-09-19 19:45:17 +02:00
|
|
|
DBUG_PRINT("enter", ("type: %d sd: %d flags: %d", type, (int)sd, flags));
|
2001-06-05 02:48:25 +02:00
|
|
|
|
2005-03-05 22:10:08 +01:00
|
|
|
#ifndef HAVE_VIO_READ_BUFF
|
|
|
|
flags&= ~VIO_BUFFERED_READ;
|
|
|
|
#endif
|
2012-08-14 16:23:34 +02:00
|
|
|
memset(vio, 0, sizeof(*vio));
|
|
|
|
vio->type= type;
|
|
|
|
vio->mysql_socket= MYSQL_INVALID_SOCKET;
|
|
|
|
mysql_socket_setfd(&vio->mysql_socket, sd);
|
2005-03-05 22:10:08 +01:00
|
|
|
vio->localhost= flags & VIO_LOCALHOST;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->read_timeout= vio->write_timeout= -1;
|
2005-03-05 22:10:08 +01:00
|
|
|
if ((flags & VIO_BUFFERED_READ) &&
|
2020-01-29 13:50:26 +01:00
|
|
|
!(vio->read_buffer= (char*)my_malloc(key_memory_vio_read_buffer,
|
|
|
|
VIO_READ_BUFFER_SIZE, MYF(MY_WME))))
|
2005-03-05 22:10:08 +01:00
|
|
|
flags&= ~VIO_BUFFERED_READ;
|
2009-11-02 23:19:58 +01:00
|
|
|
#ifdef _WIN32
|
2002-11-14 20:16:30 +01:00
|
|
|
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;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->was_timeout =vio_was_timeout;
|
2002-11-14 20:16:30 +01:00
|
|
|
vio->vioclose =vio_close_pipe;
|
|
|
|
vio->peer_addr =vio_peer_addr;
|
2012-08-17 15:46:34 +02:00
|
|
|
vio->vioblocking =vio_blocking;
|
|
|
|
vio->is_blocking =vio_is_blocking;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->io_wait =no_io_wait;
|
2009-11-10 20:36:38 +01:00
|
|
|
vio->is_connected =vio_is_connected_pipe;
|
2010-06-07 16:01:39 +02:00
|
|
|
vio->has_data =has_no_data;
|
2011-12-08 19:17:49 +01:00
|
|
|
vio->shutdown =vio_pipe_shutdown;
|
2009-11-02 23:19:58 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2002-11-14 20:16:30 +01:00
|
|
|
}
|
|
|
|
#endif
|
2018-08-20 14:06:33 +02:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
#ifdef HAVE_OPENSSL
|
2001-06-05 02:38:10 +02:00
|
|
|
if (type == VIO_TYPE_SSL)
|
|
|
|
{
|
2007-01-26 11:30:54 +01:00
|
|
|
vio->viodelete =vio_ssl_delete;
|
2006-03-10 16:41:14 +01:00
|
|
|
vio->vioerrno =vio_errno;
|
2001-06-05 02:38:10 +02:00
|
|
|
vio->read =vio_ssl_read;
|
|
|
|
vio->write =vio_ssl_write;
|
2006-03-10 16:41:14 +01:00
|
|
|
vio->fastsend =vio_fastsend;
|
|
|
|
vio->viokeepalive =vio_keepalive;
|
|
|
|
vio->should_retry =vio_should_retry;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->was_timeout =vio_was_timeout;
|
2001-06-05 02:38:10 +02:00
|
|
|
vio->vioclose =vio_ssl_close;
|
2006-03-10 16:41:14 +01:00
|
|
|
vio->peer_addr =vio_peer_addr;
|
2012-08-17 15:46:34 +02:00
|
|
|
vio->vioblocking =vio_ssl_blocking;
|
|
|
|
vio->is_blocking =vio_is_blocking;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->io_wait =vio_io_wait;
|
2009-11-10 20:36:38 +01:00
|
|
|
vio->is_connected =vio_is_connected;
|
2010-06-07 16:01:39 +02:00
|
|
|
vio->has_data =vio_ssl_has_data;
|
2011-12-08 19:17:49 +01:00
|
|
|
vio->shutdown =vio_socket_shutdown;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->timeout =vio_socket_timeout;
|
2009-11-02 23:19:58 +01:00
|
|
|
DBUG_VOID_RETURN;
|
2001-06-05 02:38:10 +02:00
|
|
|
}
|
2001-06-05 01:28:33 +02:00
|
|
|
#endif /* HAVE_OPENSSL */
|
2009-12-12 21:38:59 +01:00
|
|
|
vio->viodelete =vio_delete;
|
|
|
|
vio->vioerrno =vio_errno;
|
|
|
|
vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read;
|
|
|
|
vio->write =vio_write;
|
|
|
|
vio->fastsend =vio_fastsend;
|
|
|
|
vio->viokeepalive =vio_keepalive;
|
|
|
|
vio->should_retry =vio_should_retry;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->was_timeout =vio_was_timeout;
|
2009-12-12 21:38:59 +01:00
|
|
|
vio->vioclose =vio_close;
|
|
|
|
vio->peer_addr =vio_peer_addr;
|
2012-08-17 15:46:34 +02:00
|
|
|
vio->vioblocking =vio_blocking;
|
|
|
|
vio->is_blocking =vio_is_blocking;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->io_wait =vio_io_wait;
|
2009-12-12 21:38:59 +01:00
|
|
|
vio->is_connected =vio_is_connected;
|
2011-12-08 19:17:49 +01:00
|
|
|
vio->shutdown =vio_socket_shutdown;
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->timeout =vio_socket_timeout;
|
|
|
|
vio->has_data = ((flags & VIO_BUFFERED_READ) ?
|
|
|
|
vio_buff_has_data : has_no_data);
|
2001-06-05 02:48:25 +02:00
|
|
|
DBUG_VOID_RETURN;
|
2001-05-20 14:04:46 +02:00
|
|
|
}
|
|
|
|
|
2002-08-08 02:12:02 +02:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
/**
|
|
|
|
Reinitialize an existing Vio object.
|
|
|
|
|
|
|
|
@remark Used to rebind an initialized socket-based Vio object
|
|
|
|
to another socket-based transport type. For example,
|
|
|
|
rebind a TCP/IP transport to SSL.
|
|
|
|
|
|
|
|
@param vio A VIO object.
|
|
|
|
@param type A socket-based transport type.
|
|
|
|
@param sd The socket.
|
|
|
|
@param ssl An optional SSL structure.
|
|
|
|
@param flags Flags passed to vio_init.
|
2005-03-05 22:10:08 +01:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
@return Return value is zero on success.
|
|
|
|
*/
|
|
|
|
|
|
|
|
my_bool vio_reset(Vio* vio, enum enum_vio_type type,
|
|
|
|
my_socket sd, void *ssl __attribute__((unused)), uint flags)
|
2005-03-05 22:10:08 +01:00
|
|
|
{
|
2012-08-14 16:23:34 +02:00
|
|
|
int ret= FALSE;
|
|
|
|
Vio old_vio= *vio;
|
|
|
|
DBUG_ENTER("vio_reset");
|
|
|
|
|
|
|
|
/* The only supported rebind is from a socket-based transport type. */
|
|
|
|
DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP || vio->type == VIO_TYPE_SOCKET);
|
|
|
|
|
|
|
|
/*
|
|
|
|
Will be reinitialized depending on the flags.
|
|
|
|
Nonetheless, already buffered inside the SSL layer.
|
|
|
|
*/
|
Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabled
Essentially, the problem is that safemalloc is excruciatingly
slow as it checks all allocated blocks for overrun at each
memory management primitive, yielding a almost exponential
slowdown for the memory management functions (malloc, realloc,
free). The overrun check basically consists of verifying some
bytes of a block for certain magic keys, which catches some
simple forms of overrun. Another minor problem is violation
of aliasing rules and that its own internal list of blocks
is prone to corruption.
Another issue with safemalloc is rather the maintenance cost
as the tool has a significant impact on the server code.
Given the magnitude of memory debuggers available nowadays,
especially those that are provided with the platform malloc
implementation, maintenance of a in-house and largely obsolete
memory debugger becomes a burden that is not worth the effort
due to its slowness and lack of support for detecting more
common forms of heap corruption.
Since there are third-party tools that can provide the same
functionality at a lower or comparable performance cost, the
solution is to simply remove safemalloc. Third-party tools
can provide the same functionality at a lower or comparable
performance cost.
The removal of safemalloc also allows a simplification of the
malloc wrappers, removing quite a bit of kludge: redefinition
of my_malloc, my_free and the removal of the unused second
argument of my_free. Since free() always check whether the
supplied pointer is null, redudant checks are also removed.
Also, this patch adds unit testing for my_malloc and moves
my_realloc implementation into the same file as the other
memory allocation primitives.
client/mysqldump.c:
Pass my_free directly as its signature is compatible with the
callback type -- which wasn't the case for free_table_ent.
2010-07-08 23:20:08 +02:00
|
|
|
my_free(vio->read_buffer);
|
2012-08-14 16:23:34 +02:00
|
|
|
|
|
|
|
vio_init(vio, type, sd, flags);
|
|
|
|
|
|
|
|
/* Preserve perfschema info for this connection */
|
|
|
|
vio->mysql_socket.m_psi= old_vio.mysql_socket.m_psi;
|
|
|
|
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
|
|
vio->ssl_arg= ssl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
Propagate the timeout values. Necessary to also propagate
|
|
|
|
the underlying proprieties associated with the timeout,
|
|
|
|
such as the socket blocking mode.
|
2015-05-05 20:23:22 +02:00
|
|
|
|
|
|
|
note: old_vio.read_timeout/old_vio.write_timeout is stored in ms
|
|
|
|
but vio_timeout() takes seconds as argument, hence the / 1000
|
2012-08-14 16:23:34 +02:00
|
|
|
*/
|
|
|
|
if (old_vio.read_timeout >= 0)
|
2015-05-05 20:23:22 +02:00
|
|
|
ret|= vio_timeout(vio, 0, old_vio.read_timeout / 1000);
|
2012-08-14 16:23:34 +02:00
|
|
|
|
|
|
|
if (old_vio.write_timeout >= 0)
|
2015-05-05 20:23:22 +02:00
|
|
|
ret|= vio_timeout(vio, 1, old_vio.write_timeout / 1000);
|
2012-08-14 16:23:34 +02:00
|
|
|
|
2014-02-19 11:05:15 +01:00
|
|
|
DBUG_RETURN(MY_TEST(ret));
|
2005-03-05 22:10:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
/* Create a new VIO for socket or TCP/IP connection. */
|
2001-05-20 14:04:46 +02:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
Vio *mysql_socket_vio_new(MYSQL_SOCKET mysql_socket, enum enum_vio_type type, uint flags)
|
2001-05-20 14:04:46 +02:00
|
|
|
{
|
2001-05-31 16:18:25 +02:00
|
|
|
Vio *vio;
|
2012-08-14 16:23:34 +02:00
|
|
|
my_socket sd= mysql_socket_getfd(mysql_socket);
|
|
|
|
DBUG_ENTER("mysql_socket_vio_new");
|
2017-09-19 19:45:17 +02:00
|
|
|
DBUG_PRINT("enter", ("sd: %d", (int)sd));
|
2020-01-29 13:50:26 +01:00
|
|
|
if ((vio = (Vio*) my_malloc(key_memory_vio, sizeof(*vio), MYF(MY_WME))))
|
2001-05-20 14:04:46 +02:00
|
|
|
{
|
2012-08-14 16:23:34 +02:00
|
|
|
vio_init(vio, type, sd, flags);
|
2013-03-20 00:46:35 +01:00
|
|
|
vio->desc= (vio->type == VIO_TYPE_SOCKET ? "socket" : "TCP/IP");
|
2012-08-14 16:23:34 +02:00
|
|
|
vio->mysql_socket= mysql_socket;
|
2001-05-20 14:04:46 +02:00
|
|
|
}
|
|
|
|
DBUG_RETURN(vio);
|
|
|
|
}
|
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
/* Open the socket or TCP/IP connection and read the fnctl() status */
|
|
|
|
|
|
|
|
Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags)
|
|
|
|
{
|
|
|
|
Vio *vio;
|
|
|
|
MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET;
|
|
|
|
DBUG_ENTER("vio_new");
|
2017-09-19 19:45:17 +02:00
|
|
|
DBUG_PRINT("enter", ("sd: %d", (int)sd));
|
2012-08-14 16:23:34 +02:00
|
|
|
|
|
|
|
mysql_socket_setfd(&mysql_socket, sd);
|
|
|
|
vio = mysql_socket_vio_new(mysql_socket, type, flags);
|
2001-05-20 14:04:46 +02:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
DBUG_RETURN(vio);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2001-05-20 14:04:46 +02:00
|
|
|
|
2001-05-31 16:18:25 +02:00
|
|
|
Vio *vio_new_win32pipe(HANDLE hPipe)
|
2001-05-20 14:04:46 +02:00
|
|
|
{
|
2001-05-31 16:18:25 +02:00
|
|
|
Vio *vio;
|
2001-05-20 14:04:46 +02:00
|
|
|
DBUG_ENTER("vio_new_handle");
|
2020-01-29 13:50:26 +01:00
|
|
|
if ((vio = (Vio*) my_malloc(PSI_INSTRUMENT_ME, sizeof(Vio),MYF(MY_WME))))
|
2001-05-20 14:04:46 +02:00
|
|
|
{
|
2012-08-14 16:23:34 +02:00
|
|
|
vio_init(vio, VIO_TYPE_NAMEDPIPE, 0, VIO_LOCALHOST);
|
2013-03-20 00:46:35 +01:00
|
|
|
vio->desc= "named pipe";
|
2012-08-14 16:23:34 +02:00
|
|
|
/* Create an object for event notification. */
|
|
|
|
vio->overlapped.hEvent= CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
if (vio->overlapped.hEvent == NULL)
|
|
|
|
{
|
|
|
|
my_free(vio);
|
|
|
|
DBUG_RETURN(NULL);
|
|
|
|
}
|
|
|
|
vio->hPipe= hPipe;
|
2001-05-20 14:04:46 +02:00
|
|
|
}
|
|
|
|
DBUG_RETURN(vio);
|
|
|
|
}
|
|
|
|
|
2018-08-20 14:06:33 +02:00
|
|
|
|
2001-05-20 14:04:46 +02:00
|
|
|
#endif
|
2002-11-14 20:16:30 +01:00
|
|
|
|
2007-01-26 11:30:54 +01:00
|
|
|
|
2012-08-14 16:23:34 +02:00
|
|
|
/**
|
|
|
|
Set timeout for a network send or receive operation.
|
|
|
|
|
|
|
|
@remark A non-infinite timeout causes the socket to be
|
|
|
|
set to non-blocking mode. On infinite timeouts,
|
|
|
|
the socket is set to blocking mode.
|
|
|
|
|
|
|
|
@remark A negative timeout means an infinite timeout.
|
|
|
|
|
|
|
|
@param vio A VIO object.
|
|
|
|
@param which Whether timeout is for send (1) or receive (0).
|
|
|
|
@param timeout Timeout interval in seconds.
|
|
|
|
|
|
|
|
@return FALSE on success, TRUE otherwise.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int vio_timeout(Vio *vio, uint which, int timeout_sec)
|
|
|
|
{
|
|
|
|
int timeout_ms;
|
|
|
|
my_bool old_mode;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Vio timeouts are measured in milliseconds. Check for a possible
|
|
|
|
overflow. In case of overflow, set to infinite.
|
|
|
|
*/
|
|
|
|
if (timeout_sec > INT_MAX/1000)
|
|
|
|
timeout_ms= -1;
|
|
|
|
else
|
|
|
|
timeout_ms= (int) (timeout_sec * 1000);
|
|
|
|
|
|
|
|
/* Deduce the current timeout status mode. */
|
|
|
|
old_mode= vio->write_timeout < 0 && vio->read_timeout < 0;
|
|
|
|
|
|
|
|
if (which)
|
|
|
|
vio->write_timeout= timeout_ms;
|
|
|
|
else
|
|
|
|
vio->read_timeout= timeout_ms;
|
|
|
|
|
|
|
|
/* VIO-specific timeout handling. Might change the blocking mode. */
|
|
|
|
return vio->timeout ? vio->timeout(vio, which, old_mode) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-14 20:16:30 +01:00
|
|
|
void vio_delete(Vio* vio)
|
|
|
|
{
|
2007-01-26 11:30:54 +01:00
|
|
|
if (!vio)
|
|
|
|
return; /* It must be safe to delete null pointers. */
|
|
|
|
|
|
|
|
if (vio->type != VIO_CLOSED)
|
|
|
|
vio->vioclose(vio);
|
Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabled
Essentially, the problem is that safemalloc is excruciatingly
slow as it checks all allocated blocks for overrun at each
memory management primitive, yielding a almost exponential
slowdown for the memory management functions (malloc, realloc,
free). The overrun check basically consists of verifying some
bytes of a block for certain magic keys, which catches some
simple forms of overrun. Another minor problem is violation
of aliasing rules and that its own internal list of blocks
is prone to corruption.
Another issue with safemalloc is rather the maintenance cost
as the tool has a significant impact on the server code.
Given the magnitude of memory debuggers available nowadays,
especially those that are provided with the platform malloc
implementation, maintenance of a in-house and largely obsolete
memory debugger becomes a burden that is not worth the effort
due to its slowness and lack of support for detecting more
common forms of heap corruption.
Since there are third-party tools that can provide the same
functionality at a lower or comparable performance cost, the
solution is to simply remove safemalloc. Third-party tools
can provide the same functionality at a lower or comparable
performance cost.
The removal of safemalloc also allows a simplification of the
malloc wrappers, removing quite a bit of kludge: redefinition
of my_malloc, my_free and the removal of the unused second
argument of my_free. Since free() always check whether the
supplied pointer is null, redudant checks are also removed.
Also, this patch adds unit testing for my_malloc and moves
my_realloc implementation into the same file as the other
memory allocation primitives.
client/mysqldump.c:
Pass my_free directly as its signature is compatible with the
callback type -- which wasn't the case for free_table_ent.
2010-07-08 23:20:08 +02:00
|
|
|
my_free(vio->read_buffer);
|
|
|
|
my_free(vio);
|
2002-11-14 20:16:30 +01:00
|
|
|
}
|
2006-05-08 17:14:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Cleanup memory allocated by vio or the
|
|
|
|
components below it when application finish
|
|
|
|
|
|
|
|
*/
|
|
|
|
void vio_end(void)
|
|
|
|
{
|
2019-02-13 09:08:06 +01:00
|
|
|
#ifdef HAVE_WOLFSSL
|
|
|
|
wolfSSL_Cleanup();
|
2013-10-16 15:37:11 +02:00
|
|
|
#elif defined(HAVE_OPENSSL)
|
|
|
|
// This one is needed on the client side
|
|
|
|
ERR_remove_state(0);
|
|
|
|
ERR_free_strings();
|
|
|
|
EVP_cleanup();
|
|
|
|
CRYPTO_cleanup_all_ex_data();
|
2006-05-08 17:14:06 +02:00
|
|
|
#endif
|
|
|
|
}
|