From 8a758f77e3ad4f55f4b3f6d9d0b17d3b5d294254 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Tue, 18 Nov 2008 19:18:51 +0100 Subject: [PATCH] When in Ruby 1.9, release the global interpreter lock while performing a query, so that other threads can still run. --- ext/mysql.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/ext/mysql.c b/ext/mysql.c index 02c2f62..aa8631d 100644 --- a/ext/mysql.c +++ b/ext/mysql.c @@ -719,18 +719,43 @@ static VALUE use_result(VALUE obj) } static VALUE res_free(VALUE); + +typedef struct { + MYSQL *m; + const char *data; + unsigned long len; +} QueryArgs; + +static VALUE blocking_query(void *data) +{ + QueryArgs *args = (QueryArgs *) data; + return (VALUE) mysql_real_query(args->m, args->data, args->len); +} + /* query(sql) */ static VALUE query(VALUE obj, VALUE sql) { int loop = 0; MYSQL* m = GetHandler(obj); + QueryArgs args; + int result; + Check_Type(sql, T_STRING); if (GetMysqlStruct(obj)->connection == Qfalse) { rb_raise(eMysql, "query: not connected"); } if (rb_block_given_p()) { - if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0) + #ifdef RUBY_VM + args.m = m; + args.data = RSTRING_PTR(sql); + args.len = RSTRING_LEN(sql); + result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0); + #else + result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)); + #endif + if (result != 0) mysql_raise(m); + do { MYSQL_RES* res = mysql_store_result(m); if (res == NULL) { @@ -749,7 +774,16 @@ static VALUE query(VALUE obj, VALUE sql) #endif return obj; } - if (mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)) != 0) + + #ifdef RUBY_VM + args.m = m; + args.data = RSTRING_PTR(sql); + args.len = RSTRING_LEN(sql); + result = (int) rb_thread_blocking_region(blocking_query, &args, RUBY_UBF_PROCESS, 0); + #else + result = mysql_real_query(m, RSTRING_PTR(sql), RSTRING_LEN(sql)); + #endif + if (result != 0) mysql_raise(m); if (GetMysqlStruct(obj)->query_with_result == Qfalse) return obj;