1
0
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:
Georg Richter
2016-08-24 19:25:15 +02:00
parent fbf6fd1598
commit 2a7cc977fb
8 changed files with 137 additions and 49 deletions

View File

@@ -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 {

View File

@@ -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;
} }
/* }}} */ /* }}} */

View File

@@ -920,24 +920,6 @@ void ps_fetch_string(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
static 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,
we do conversion from string */
if (!(field->flags & BINARY_FLAG) ||
(r_param->buffer_type != MYSQL_TYPE_NEWDECIMAL &&
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); ulong field_length= *r_param->length= net_field_length(row);
uchar *current_pos= (*row) + r_param->offset, uchar *current_pos= (*row) + r_param->offset,
@@ -962,7 +944,6 @@ void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
field_length--; field_length--;
(*row)+= field_length; (*row)+= field_length;
} }
}
/* }}} */ /* }}} */
/* {{{ _mysqlnd_init_ps_subsystem */ /* {{{ _mysqlnd_init_ps_subsystem */

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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},