Merge branch '19_non_gvl_connect_original'

This commit is contained in:
Roger Pack 2009-04-18 22:23:17 +00:00
commit 497be9ca26
3 changed files with 109 additions and 8 deletions

View File

@ -45,7 +45,9 @@ else
exit 1
end
# check for 1.9
if have_func('rb_thread_blocking_region') and have_macro('RUBY_UBF_IO', 'ruby.h')
$CFLAGS += " -DHAVE_TBR "
$CPPFLAGS << " -DHAVE_TBR "
end

View File

@ -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 *) &param_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);
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 */

View File

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