You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
Shared memory fixes
This commit is contained in:
@@ -55,6 +55,8 @@ enum enum_pvio_operation {
|
|||||||
PVIO_WRITE=1
|
PVIO_WRITE=1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SHM_DEFAULT_NAME "MYSQL"
|
||||||
|
|
||||||
struct st_pvio_callback;
|
struct st_pvio_callback;
|
||||||
|
|
||||||
typedef struct st_pvio_callback {
|
typedef struct st_pvio_callback {
|
||||||
|
@@ -139,9 +139,11 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
|
|||||||
/* {{{ my_bool ma_pvio_is_alive */
|
/* {{{ my_bool ma_pvio_is_alive */
|
||||||
my_bool ma_pvio_is_alive(MARIADB_PVIO *pvio)
|
my_bool ma_pvio_is_alive(MARIADB_PVIO *pvio)
|
||||||
{
|
{
|
||||||
|
if (!pvio)
|
||||||
|
return FALSE;
|
||||||
if (pvio->methods->is_alive)
|
if (pvio->methods->is_alive)
|
||||||
return pvio->methods->is_alive(pvio);
|
return pvio->methods->is_alive(pvio);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@@ -921,47 +921,28 @@ static
|
|||||||
void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
|
void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
|
||||||
unsigned char **row)
|
unsigned char **row)
|
||||||
{
|
{
|
||||||
/* If r_praram->buffer_type is not a binary type or binary_flag isn't set,
|
ulong field_length= *r_param->length= net_field_length(row);
|
||||||
we do conversion from string */
|
uchar *current_pos= (*row) + r_param->offset,
|
||||||
if (!(field->flags & BINARY_FLAG) ||
|
*end= (*row) + field_length;
|
||||||
(r_param->buffer_type != MYSQL_TYPE_NEWDECIMAL &&
|
size_t copylen= 0;
|
||||||
r_param->buffer_type != MYSQL_TYPE_DECIMAL &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_GEOMETRY &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_ENUM &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_SET &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_TINY_BLOB &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_MEDIUM_BLOB &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_LONG_BLOB &&
|
|
||||||
r_param->buffer_type != MYSQL_TYPE_BLOB))
|
|
||||||
{
|
|
||||||
ps_fetch_string(r_param, field, row);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ulong field_length= *r_param->length= net_field_length(row);
|
|
||||||
uchar *current_pos= (*row) + r_param->offset,
|
|
||||||
*end= (*row) + field_length;
|
|
||||||
size_t copylen= 0;
|
|
||||||
|
|
||||||
if (current_pos < end)
|
if (current_pos < end)
|
||||||
|
{
|
||||||
|
copylen= end - current_pos;
|
||||||
|
if (r_param->buffer_length)
|
||||||
{
|
{
|
||||||
copylen= end - current_pos;
|
memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length));
|
||||||
if (r_param->buffer_length)
|
if (copylen < r_param->buffer_length &&
|
||||||
{
|
r_param->buffer_type == MYSQL_TYPE_STRING)
|
||||||
memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length));
|
((char *)r_param->buffer)[copylen]= 0;
|
||||||
if (copylen < r_param->buffer_length &&
|
|
||||||
r_param->buffer_type == MYSQL_TYPE_STRING)
|
|
||||||
((char *)r_param->buffer)[copylen]= 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*r_param->error= copylen > r_param->buffer_length;
|
|
||||||
/* don't count trailing zero if we fetch into string */
|
|
||||||
if (r_param->buffer_type == MYSQL_TYPE_STRING &&
|
|
||||||
!*r_param->error)
|
|
||||||
field_length--;
|
|
||||||
(*row)+= field_length;
|
|
||||||
}
|
}
|
||||||
|
*r_param->error= copylen > r_param->buffer_length;
|
||||||
|
/* don't count trailing zero if we fetch into string */
|
||||||
|
if (r_param->buffer_type == MYSQL_TYPE_STRING &&
|
||||||
|
!*r_param->error)
|
||||||
|
field_length--;
|
||||||
|
(*row)+= field_length;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@@ -1221,8 +1221,15 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY ||
|
||||||
|
mysql->options.shared_memory_base_name)
|
||||||
|
{
|
||||||
|
cinfo.host= mysql->options.shared_memory_base_name;
|
||||||
|
cinfo.type= PVIO_TYPE_SHAREDMEM;
|
||||||
|
sprintf(host_info=buff,ER(CR_SHARED_MEMORY_CONNECTION), cinfo.host ? cinfo.host : SHM_DEFAULT_NAME);
|
||||||
|
}
|
||||||
/* named pipe */
|
/* named pipe */
|
||||||
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
else if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
||||||
(host && strcmp(host,LOCAL_HOST_NAMEDPIPE) == 0))
|
(host && strcmp(host,LOCAL_HOST_NAMEDPIPE) == 0))
|
||||||
{
|
{
|
||||||
cinfo.type= PVIO_TYPE_NAMEDPIPE;
|
cinfo.type= PVIO_TYPE_NAMEDPIPE;
|
||||||
@@ -2621,6 +2628,11 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
case MYSQL_OPT_PROTOCOL:
|
case MYSQL_OPT_PROTOCOL:
|
||||||
mysql->options.protocol= *((uint *)arg1);
|
mysql->options.protocol= *((uint *)arg1);
|
||||||
break;
|
break;
|
||||||
|
#ifdef _WIN32
|
||||||
|
case MYSQL_SHARED_MEMORY_BASE_NAME:
|
||||||
|
OPT_SET_VALUE_STR(&mysql->options, shared_memory_base_name, arg1);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case MYSQL_OPT_READ_TIMEOUT:
|
case MYSQL_OPT_READ_TIMEOUT:
|
||||||
mysql->options.read_timeout= *(uint *)arg1;
|
mysql->options.read_timeout= *(uint *)arg1;
|
||||||
break;
|
break;
|
||||||
|
@@ -46,6 +46,7 @@ int pvio_npipe_keepalive(MARIADB_PVIO *pvio);
|
|||||||
my_bool pvio_npipe_get_handle(MARIADB_PVIO *pvio, void *handle);
|
my_bool pvio_npipe_get_handle(MARIADB_PVIO *pvio, void *handle);
|
||||||
my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio);
|
my_bool pvio_npipe_is_blocking(MARIADB_PVIO *pvio);
|
||||||
int pvio_npipe_shutdown(MARIADB_PVIO *pvio);
|
int pvio_npipe_shutdown(MARIADB_PVIO *pvio);
|
||||||
|
my_bool pvio_npipe_is_alive(MARIADB_PVIO *pvio);
|
||||||
|
|
||||||
struct st_ma_pvio_methods pvio_npipe_methods= {
|
struct st_ma_pvio_methods pvio_npipe_methods= {
|
||||||
pvio_npipe_set_timeout,
|
pvio_npipe_set_timeout,
|
||||||
@@ -62,7 +63,7 @@ struct st_ma_pvio_methods pvio_npipe_methods= {
|
|||||||
pvio_npipe_keepalive,
|
pvio_npipe_keepalive,
|
||||||
pvio_npipe_get_handle,
|
pvio_npipe_get_handle,
|
||||||
pvio_npipe_is_blocking,
|
pvio_npipe_is_blocking,
|
||||||
NULL,
|
pvio_npipe_is_alive,
|
||||||
NULL,
|
NULL,
|
||||||
pvio_npipe_shutdown
|
pvio_npipe_shutdown
|
||||||
};
|
};
|
||||||
@@ -367,4 +368,16 @@ int pvio_npipe_shutdown(MARIADB_PVIO *pvio)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool pvio_npipe_is_alive(MARIADB_PVIO *pvio)
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
if (!pvio || !pvio->data)
|
||||||
|
return FALSE;
|
||||||
|
handle= ((struct st_pvio_npipe *)pvio->data)->pipe;
|
||||||
|
/* Copy data fron named pipe without removing it */
|
||||||
|
if (PeekNamedPipe(handle, NULL, 0, NULL, NULL, NULL))
|
||||||
|
return TRUE;
|
||||||
|
return test(GetLastError() != ERROR_BROKEN_PIPE);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ma_string.h>
|
#include <ma_string.h>
|
||||||
|
|
||||||
#define SHM_DEFAULT_NAME "MYSQL"
|
|
||||||
#define PVIO_SHM_BUFFER_SIZE 16000 + 4
|
#define PVIO_SHM_BUFFER_SIZE 16000 + 4
|
||||||
|
|
||||||
my_bool pvio_shm_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout);
|
my_bool pvio_shm_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout);
|
||||||
@@ -41,6 +40,8 @@ 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_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
|
||||||
my_bool pvio_shm_close(MARIADB_PVIO *pvio);
|
my_bool pvio_shm_close(MARIADB_PVIO *pvio);
|
||||||
int pvio_shm_shutdown(MARIADB_PVIO *pvio);
|
int pvio_shm_shutdown(MARIADB_PVIO *pvio);
|
||||||
|
my_bool pvio_shm_is_alive(MARIADB_PVIO *pvio);
|
||||||
|
my_bool pvio_shm_get_handle(MARIADB_PVIO *pvio, void *handle);
|
||||||
|
|
||||||
struct st_ma_pvio_methods pvio_shm_methods= {
|
struct st_ma_pvio_methods pvio_shm_methods= {
|
||||||
pvio_shm_set_timeout,
|
pvio_shm_set_timeout,
|
||||||
@@ -55,9 +56,9 @@ struct st_ma_pvio_methods pvio_shm_methods= {
|
|||||||
pvio_shm_close,
|
pvio_shm_close,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
pvio_shm_get_handle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
pvio_shm_is_alive,
|
||||||
NULL,
|
|
||||||
NULL,
|
NULL,
|
||||||
pvio_shm_shutdown
|
pvio_shm_shutdown
|
||||||
};
|
};
|
||||||
@@ -262,9 +263,7 @@ my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
base_memory_name= (cinfo->mysql->options.shared_memory_base_name) ?
|
base_memory_name= (cinfo->host) ? cinfo->host : SHM_DEFAULT_NAME;
|
||||||
cinfo->mysql->options.shared_memory_base_name : SHM_DEFAULT_NAME;
|
|
||||||
|
|
||||||
|
|
||||||
if (!(shm_name= (char *)LocalAlloc(LMEM_ZEROINIT, strlen(base_memory_name) + 40)))
|
if (!(shm_name= (char *)LocalAlloc(LMEM_ZEROINIT, strlen(base_memory_name) + 40)))
|
||||||
{
|
{
|
||||||
@@ -447,5 +446,24 @@ int pvio_shm_shutdown(MARIADB_PVIO *pvio)
|
|||||||
return (SetEvent(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED]) ? 0 : 1);
|
return (SetEvent(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED]) ? 0 : 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool pvio_shm_is_alive(MARIADB_PVIO *pvio)
|
||||||
|
{
|
||||||
|
PVIO_SHM *pvio_shm;
|
||||||
|
if (!pvio || !pvio->data)
|
||||||
|
return FALSE;
|
||||||
|
pvio_shm= (PVIO_SHM *)pvio->data;
|
||||||
|
return WaitForSingleObject(pvio_shm->event[PVIO_SHM_CONNECTION_CLOSED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
my_bool pvio_shm_get_handle(MARIADB_PVIO *pvio, void *handle)
|
||||||
|
{
|
||||||
|
PVIO_SHM *pvio_shm;
|
||||||
|
*(HANDLE **)handle= 0;
|
||||||
|
if (!pvio || !pvio->data)
|
||||||
|
return FALSE;
|
||||||
|
*(HANDLE **)handle= (HANDLE **)((PVIO_SHM*)pvio->data)->event;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -122,6 +122,9 @@ static char *password = 0;
|
|||||||
static unsigned int port = 0;
|
static unsigned int port = 0;
|
||||||
static char *socketname = 0;
|
static char *socketname = 0;
|
||||||
static char *username = 0;
|
static char *username = 0;
|
||||||
|
#ifdef _WIN32
|
||||||
|
static int protocol= 0;
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
static struct my_option test_options[] =
|
static struct my_option test_options[] =
|
||||||
{
|
{
|
||||||
@@ -312,19 +315,24 @@ static void usage()
|
|||||||
printf("-d database\n");
|
printf("-d database\n");
|
||||||
printf("-S socketname\n");
|
printf("-S socketname\n");
|
||||||
printf("-P port number\n");
|
printf("-P port number\n");
|
||||||
|
printf("-w protocol mode (windows only: 1= named pipe, 2= shared memory)");
|
||||||
printf("? displays this help and exits\n");
|
printf("? displays this help and exits\n");
|
||||||
}
|
|
||||||
|
|
||||||
void get_options(int argc, char **argv)
|
void get_options(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c= 0;
|
int c= 0;
|
||||||
|
|
||||||
while ((c=getopt(argc,argv, "h:u:p:d:P:S:?")) >= 0)
|
while ((c=getopt(argc,argv, "h:u:p:d:w:P:S:?")) >= 0)
|
||||||
{
|
{
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
hostname= optarg;
|
hostname= optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
#ifdef _WIN32
|
||||||
|
protocol= atoi(optarg);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
username= optarg;
|
username= optarg;
|
||||||
break;
|
break;
|
||||||
@@ -388,7 +396,12 @@ MYSQL *test_connect(struct my_tests_st *test) {
|
|||||||
diag("%s", "mysql_init failed - exiting");
|
diag("%s", "mysql_init failed - exiting");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
switch (protocol) {
|
||||||
|
case 1: /* named pipe */
|
||||||
|
case 2: /* shared memory */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &truncation_report);
|
mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, &truncation_report);
|
||||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
|
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
|
||||||
|
|
||||||
@@ -414,6 +427,7 @@ MYSQL *test_connect(struct my_tests_st *test) {
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
printf("Connection: %s\n", mysql->host_info);
|
||||||
return(mysql);
|
return(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4857,7 +4857,53 @@ int test_notrunc(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_bit2tiny(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
MYSQL_BIND bind[2];
|
||||||
|
char data[11];
|
||||||
|
unsigned long length[2];
|
||||||
|
my_bool is_null[2], error[2];
|
||||||
|
char *query = "SELECT val FROM justbit";
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
mysql_query(mysql, "DROP TABLE IF EXISTS justbit");
|
||||||
|
mysql_query(mysql, "CREATE TABLE justbit(val bit(1) not null)");
|
||||||
|
mysql_query(mysql, "INSERT INTO justbit values (1)");
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
memset(bind, '\0', sizeof(bind));
|
||||||
|
|
||||||
|
bind[0].buffer_type= MYSQL_TYPE_TINY;
|
||||||
|
bind[0].buffer= &data[0];
|
||||||
|
bind[0].buffer_length= 1;
|
||||||
|
bind[0].is_null= &is_null[0];
|
||||||
|
bind[0].length= &length[0];
|
||||||
|
bind[0].error= &error[0];
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_result(stmt, bind);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_store_result(stmt);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
mysql_stmt_fetch(stmt);
|
||||||
|
|
||||||
|
FAIL_IF(data[0] != 1, "Value should be 1");
|
||||||
|
|
||||||
|
mysql_stmt_free_result(stmt);
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
|
{"test_bit2tiny", test_bit2tiny, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc97", test_conc97, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_conc97", test_conc97, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc83", test_conc83, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_conc83", test_conc83, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{"test_conc60", test_conc60, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc60", test_conc60, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
|
Reference in New Issue
Block a user