Merge branch '19_non_gvl_connect_original'
This commit is contained in:
commit
497be9ca26
@ -45,7 +45,9 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# check for 1.9
|
||||||
if have_func('rb_thread_blocking_region') and have_macro('RUBY_UBF_IO', 'ruby.h')
|
if have_func('rb_thread_blocking_region') and have_macro('RUBY_UBF_IO', 'ruby.h')
|
||||||
|
$CFLAGS += " -DHAVE_TBR "
|
||||||
$CPPFLAGS << " -DHAVE_TBR "
|
$CPPFLAGS << " -DHAVE_TBR "
|
||||||
end
|
end
|
||||||
|
|
||||||
|
108
ext/mysql.c
108
ext/mysql.c
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#ifndef RSTRING_PTR
|
#ifndef RSTRING_PTR
|
||||||
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
#define RSTRING_PTR(str) RSTRING(str)->ptr
|
||||||
#endif
|
#endif
|
||||||
@ -233,8 +234,71 @@ static VALUE init(VALUE klass)
|
|||||||
return obj;
|
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) */
|
/* 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;
|
VALUE host, user, passwd, db, port, sock, flag;
|
||||||
char *h, *u, *p, *d, *s;
|
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);
|
obj = Data_Make_Struct(klass, struct mysql, 0, free_mysql, myp);
|
||||||
#if MYSQL_VERSION_ID >= 32200
|
#if MYSQL_VERSION_ID >= 32200
|
||||||
mysql_init(&myp->handler);
|
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)
|
if(mysql_real_connect(&myp->handler, h, u, p, d, pp, s, f) == NULL)
|
||||||
|
# endif
|
||||||
#elif MYSQL_VERSION_ID >= 32115
|
#elif MYSQL_VERSION_ID >= 32115
|
||||||
if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL)
|
if (mysql_real_connect(&myp->handler, h, u, p, pp, s, f) == NULL)
|
||||||
#else
|
#else
|
||||||
@ -694,13 +762,38 @@ static VALUE my_stat(VALUE obj)
|
|||||||
return rb_tainted_str_new2(s);
|
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() */
|
/* store_result() */
|
||||||
static VALUE store_result(VALUE obj)
|
static VALUE store_result(VALUE obj)
|
||||||
{
|
{
|
||||||
MYSQL* m = GetHandler(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)
|
if (res == NULL)
|
||||||
mysql_raise(m);
|
mysql_raise(m);
|
||||||
|
|
||||||
return mysqlres2obj(res);
|
return mysqlres2obj(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,12 +893,17 @@ static VALUE socket(VALUE obj)
|
|||||||
MYSQL* m = GetHandler(obj);
|
MYSQL* m = GetHandler(obj);
|
||||||
return INT2NUM(m->net.fd);
|
return INT2NUM(m->net.fd);
|
||||||
}
|
}
|
||||||
/* socket_type */
|
/* socket_type --currently returns true or false, needs some work */
|
||||||
static VALUE socket_type(VALUE obj)
|
static VALUE socket_type(VALUE obj)
|
||||||
{
|
{
|
||||||
MYSQL* m = GetHandler(obj);
|
MYSQL* m = GetHandler(obj);
|
||||||
|
char *answer;
|
||||||
VALUE description = vio_description( m->net.vio );
|
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 */
|
/* blocking */
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# shows the effect of using .all_hashes instead of looping on each hash
|
# 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
|
# 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]
|
# 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 'rubygems'
|
||||||
require 'mysqlplus'
|
require 'mysqlplus'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user