1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

CONC-184 : provide a function to cancel a current connection

(without invalidating MYSQL struct, without sending KILL)
This apparently is useful for replication handling in the server
This commit is contained in:
Vladislav Vaintroub
2016-05-21 12:35:06 +00:00
parent 07877e61cf
commit 437b9cd1e4
6 changed files with 61 additions and 4 deletions

View File

@@ -105,6 +105,7 @@ struct st_ma_pvio_methods
my_bool (*is_blocking)(MARIADB_PVIO *pvio);
my_bool (*is_alive)(MARIADB_PVIO *pvio);
my_bool (*has_data)(MARIADB_PVIO *pvio, ssize_t *data_len);
int(*shutdown)(MARIADB_PVIO *pvio);
};
/* Function prototypes */

View File

@@ -570,6 +570,7 @@ my_socket STDCALL mysql_get_socket(MYSQL *mysql);
unsigned int STDCALL mysql_get_timeout_value(const MYSQL *mysql);
unsigned int STDCALL mysql_get_timeout_value_ms(const MYSQL *mysql);
my_bool STDCALL mariadb_reconnect(MYSQL *mysql);
int STDCALL mariadb_cancel(MYSQL *mysql);
/* Async API */
int STDCALL mysql_close_start(MYSQL *sock);

View File

@@ -3804,6 +3804,24 @@ my_bool STDCALL mariadb_get_info(MYSQL *mysql, enum mariadb_value value, void *a
return mariadb_get_infov(mysql, value, arg);
}
/*
Immediately aborts connection, making all subsequent read/write operations fail.
Does not invalidate memory used for mysql structure, nor closes any communication
channels - mysql_close is still needed.
Useful to break long query, in situation sending KILL is not possible.
*/
int STDCALL mariadb_cancel(MYSQL *mysql)
{
if (!mysql || !mysql->net.pvio || !mysql->net.pvio->methods || !mysql->net.pvio->methods->shutdown)
{
return 1;
}
else
{
MARIADB_PVIO *pvio = mysql->net.pvio;
return pvio->methods->shutdown(pvio);
}
}
#undef STDCALL
/* API functions for usage in dynamic plugins */
struct st_mariadb_api MARIADB_API=

View File

@@ -45,6 +45,7 @@ int pvio_npipe_fast_send(MARIADB_PVIO *pvio);
int pvio_npipe_keepalive(MARIADB_PVIO *pvio);
my_bool pvio_npipe_get_handle(MARIADB_PVIO *pvio, void *handle);
my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio);
int pvio_npipe_shutdown(MARIADB_PVIO *pvio);
struct st_ma_pvio_methods pvio_npipe_methods= {
pvio_npipe_set_timeout,
@@ -60,7 +61,8 @@ struct st_ma_pvio_methods pvio_npipe_methods= {
pvio_npipe_fast_send,
pvio_npipe_keepalive,
pvio_npipe_get_handle,
pvio_npipe_is_blocking
pvio_npipe_is_blocking,
pvio_npipe_shutdown
};
#ifndef HAVE_NPIPE_DYNAMIC
@@ -354,4 +356,13 @@ my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio)
return (flags & PIPE_NOWAIT) ? 0 : 1;
}
int pvio_npipe_shutdown(MARIADB_PVIO *pvio)
{
HANDLE h;
if (pvio_npipe_get_handle(pvio, &h) == 0)
{
return(CancelIoEx(h, NULL) ? 0 : 1);
}
return 1;
}
#endif

View File

@@ -40,7 +40,7 @@ int pvio_shm_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout
my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
my_bool pvio_shm_close(MARIADB_PVIO *pvio);
int pvio_shm_shutdown(MARIADB_PVIO *pvio);
struct st_ma_pvio_methods pvio_shm_methods= {
pvio_shm_set_timeout,
@@ -57,7 +57,9 @@ struct st_ma_pvio_methods pvio_shm_methods= {
NULL,
NULL,
NULL,
NULL
NULL,
NULL,
pvio_shm_shutdown
};
#ifndef HAVE_SHMEM_DYNAMIC
@@ -438,5 +440,11 @@ my_bool pvio_shm_is_blocking(MARIADB_PVIO *pvio)
return 1;
}
int pvio_shm_shutdown(MARIADB_PVIO *pvio)
{
PVIO_SHM *pvio_shm= (PVIO_SHM *)pvio->data;
if (pvio_shm)
return (SetEvent(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED]) ? 0 : 1);
}
#endif

View File

@@ -76,6 +76,7 @@ my_bool pvio_socket_get_handle(MARIADB_PVIO *pvio, void *handle);
my_bool pvio_socket_is_blocking(MARIADB_PVIO *pvio);
my_bool pvio_socket_is_alive(MARIADB_PVIO *pvio);
my_bool pvio_socket_has_data(MARIADB_PVIO *pvio, ssize_t *data_len);
int pvio_socket_shutdown(MARIADB_PVIO *pvio);
static int pvio_socket_init(char *unused1,
size_t unused2,
@@ -99,7 +100,8 @@ struct st_ma_pvio_methods pvio_socket_methods= {
pvio_socket_get_handle,
pvio_socket_is_blocking,
pvio_socket_is_alive,
pvio_socket_has_data
pvio_socket_has_data,
pvio_socket_shutdown
};
#ifndef HAVE_SOCKET_DYNAMIC
@@ -1023,3 +1025,19 @@ my_bool pvio_socket_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
return 0;
}
/* }}} */
int pvio_socket_shutdown(MARIADB_PVIO *pvio)
{
int rc = 0;
if (pvio && pvio->data)
{
my_socket s = ((struct st_pvio_socket *)pvio->data)->socket;
#ifdef _WIN32
rc = shutdown(s, SD_BOTH);
CancelIoEx((HANDLE)s, NULL);
#else
rc = shutdown(s, SHUT_RDWR);
#endif
}
return -1;
}