Merge branch '19_non_gvl_connect_original'
This commit is contained in:
commit
497be9ca26
@ -45,8 +45,10 @@ else
|
||||
exit 1
|
||||
end
|
||||
|
||||
# check for 1.9
|
||||
if have_func('rb_thread_blocking_region') and have_macro('RUBY_UBF_IO', 'ruby.h')
|
||||
$CPPFLAGS << " -DHAVE_TBR"
|
||||
$CFLAGS += " -DHAVE_TBR "
|
||||
$CPPFLAGS << " -DHAVE_TBR "
|
||||
end
|
||||
|
||||
# make mysql constant
|
||||
|
110
ext/mysql.c
110
ext/mysql.c
@ -6,6 +6,7 @@
|
||||
|
||||
#include <ruby.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef RSTRING_PTR
|
||||
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
||||
#endif
|
||||
@ -233,8 +234,71 @@ static VALUE init(VALUE klass)
|
||||
return obj;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TBR
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *func_pointer;
|
||||
int param_count;
|
||||
void *args[10];
|
||||
} arg_holder, *arg_holder2;
|
||||
|
||||
|
||||
static void call_single_function_rb_thread_blocking_region(void *arg_holder_in);
|
||||
|
||||
void *rb_thread_blocking_region_variable_params(int number, ...)
|
||||
{
|
||||
va_list param_pt; // TODO handle all the way through 10 args
|
||||
va_start(param_pt, number);
|
||||
int index;
|
||||
arg_holder param_storer;
|
||||
void *func_pointer = va_arg(param_pt, void *);
|
||||
void *interrupter = va_arg(param_pt, void *);
|
||||
param_storer.func_pointer = func_pointer;
|
||||
int real_param_count = number - 2;
|
||||
param_storer.param_count = real_param_count;
|
||||
for(index = 0 ; index < real_param_count ; index++)
|
||||
{
|
||||
void *arg = va_arg(param_pt, void *);
|
||||
param_storer.args[index] = arg;
|
||||
|
||||
}
|
||||
va_end(param_pt);
|
||||
|
||||
return rb_thread_blocking_region((rb_blocking_function_t *)call_single_function_rb_thread_blocking_region, (void *) ¶m_storer, interrupter, 0);
|
||||
|
||||
}
|
||||
|
||||
static void call_single_function_rb_thread_blocking_region(void *arg_holder_in)
|
||||
{
|
||||
arg_holder *params_and_func = (arg_holder *) arg_holder_in;
|
||||
int param_count = params_and_func->param_count;
|
||||
void *result;
|
||||
if(param_count == 3)
|
||||
{
|
||||
void * (*pt2Func)(void *, void *, void *) = params_and_func->func_pointer;
|
||||
result = (*pt2Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2]);
|
||||
}else if(param_count == 6)
|
||||
{
|
||||
void * (*pt2Func)(void *, void *, void *, void *, void *, void *) = params_and_func->func_pointer;
|
||||
result = (*pt2Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2], params_and_func->args[3], params_and_func->args[4], params_and_func->args[5]);
|
||||
}else if(param_count == 8)
|
||||
{
|
||||
void * (*pt2Func)(void *, void *, void *, void *, void *, void *, void *, void *) = params_and_func->func_pointer;
|
||||
result = (*pt2Func)(params_and_func->args[0], params_and_func->args[1], params_and_func->args[2], params_and_func->args[3], params_and_func->args[4], params_and_func->args[5], params_and_func->args[6], params_and_func->args[7]);
|
||||
}else
|
||||
{
|
||||
printf("UN nonwn param count--please add it! %d\n", param_count);
|
||||
result = Qnil;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* real_connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, sock=nil, flag=nil) */
|
||||
static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
|
||||
static VALUE real_connect(int argc, VALUE* argv, VALUE klass) /* actually gets run */
|
||||
{
|
||||
VALUE host, user, passwd, db, port, sock, flag;
|
||||
char *h, *u, *p, *d, *s;
|
||||
@ -260,8 +324,12 @@ static VALUE real_connect(int argc, VALUE* argv, VALUE klass)
|
||||
|
||||
obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
|
||||
#if MYSQL_VERSION_ID >= 32200
|
||||
mysql_init(&myp->handler);
|
||||
if (mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL)
|
||||
mysql_init(&myp->handler); /* we get here */
|
||||
# ifdef HAVE_TBR
|
||||
if( (int) rb_thread_blocking_region_variable_params(10, &mysql_real_connect, 8, &myp->handler, h, u, p, d, pp, s, f) == NULL)
|
||||
# else
|
||||
if(mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL)
|
||||
# endif
|
||||
#elif MYSQL_VERSION_ID >= 32115
|
||||
if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL)
|
||||
#else
|
||||
@ -694,13 +762,38 @@ static VALUE my_stat(VALUE obj)
|
||||
return rb_tainted_str_new2(s);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MYSQL *mysql_instance;
|
||||
MYSQL_RES **store_it_here;
|
||||
|
||||
} mysql_result_to_here_t,
|
||||
*shared_stuff_p;
|
||||
|
||||
static VALUE store_result_to_location(void *settings_in)
|
||||
{
|
||||
mysql_result_to_here_t *settings = (mysql_result_to_here_t *) settings_in;
|
||||
*(settings->store_it_here) = mysql_store_result(settings->mysql_instance); // this one runs a good long while for very large queries
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/* store_result() */
|
||||
static VALUE store_result(VALUE obj)
|
||||
{
|
||||
MYSQL* m = GetHandler(obj);
|
||||
MYSQL_RES* res = mysql_store_result(m);
|
||||
MYSQL_RES* res = NULL;
|
||||
#ifndef HAVE_TBR
|
||||
res = mysql_store_result(m);
|
||||
#else
|
||||
mysql_result_to_here_t linker;
|
||||
linker.mysql_instance = m;
|
||||
linker.store_it_here = &res;
|
||||
rb_thread_blocking_region(store_result_to_location, (void *) &linker, RUBY_UBF_IO, 0); /* not sure if this should be RUBY_UBF_IO or RUBY_UBF_PROCESS here -- see Ruby 1.9 ChangeLog */
|
||||
#endif
|
||||
|
||||
if (res == NULL)
|
||||
mysql_raise(m);
|
||||
|
||||
return mysqlres2obj(res);
|
||||
}
|
||||
|
||||
@ -800,12 +893,17 @@ static VALUE socket(VALUE obj)
|
||||
MYSQL* m = GetHandler(obj);
|
||||
return INT2NUM(m->net.fd);
|
||||
}
|
||||
/* socket_type */
|
||||
/* socket_type --currently returns true or false, needs some work */
|
||||
static VALUE socket_type(VALUE obj)
|
||||
{
|
||||
MYSQL* m = GetHandler(obj);
|
||||
char *answer;
|
||||
VALUE description = vio_description( m->net.vio );
|
||||
return (VALUE) NILorSTRING( description );
|
||||
answer = NILorSTRING( description );
|
||||
if(answer)
|
||||
return Qtrue; // TODO return a ruby string
|
||||
else
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/* blocking */
|
||||
|
@ -1,7 +1,8 @@
|
||||
# shows the effect of using .all_hashes instead of looping on each hash
|
||||
# run it by substiting in a 'long' [many row] query for the query variable and toggling use_all_hashes here at the top
|
||||
# note that we load all the rows first, then run .all_hashes on the result [to see more easily the effect of all hashes]
|
||||
# on my machine and a 200_000 row table, it took 3.38s versus 3.65s
|
||||
# on my machine and a 200_000 row table, it took 3.38s versus 3.65s for the old .each_hash way [note also that .each_hash is
|
||||
# almost as fast, now, as .all_hashes--they've both been optimized]
|
||||
require 'rubygems'
|
||||
require 'mysqlplus'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user