Skip to content

Commit 36f5509

Browse files
committed
Merge pull request #705 from kamipo/fixes_694
Avoid GC run between mysql_stmt_execute and mysql_stmt_store_result
2 parents 924d934 + 19d93b5 commit 36f5509

File tree

3 files changed

+18
-36
lines changed

3 files changed

+18
-36
lines changed

ext/mysql2/client.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static VALUE allocate(VALUE klass) {
259259
mysql_client_wrapper * wrapper;
260260
obj = Data_Make_Struct(klass, mysql_client_wrapper, rb_mysql_client_mark, rb_mysql_client_free, wrapper);
261261
wrapper->encoding = Qnil;
262-
MARK_CONN_INACTIVE(self);
262+
wrapper->active_thread = Qnil;
263263
wrapper->automatic_close = 1;
264264
wrapper->server_version = 0;
265265
wrapper->reconnect_enabled = 0;
@@ -373,7 +373,7 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
373373
if (wrapper->connect_timeout)
374374
mysql_options(wrapper->client, MYSQL_OPT_CONNECT_TIMEOUT, &wrapper->connect_timeout);
375375
if (rv == Qfalse)
376-
return rb_raise_mysql2_error(wrapper);
376+
rb_raise_mysql2_error(wrapper);
377377
}
378378

379379
wrapper->server_version = mysql_get_server_version(wrapper->client);
@@ -418,8 +418,8 @@ static VALUE do_send_query(void *args) {
418418
mysql_client_wrapper *wrapper = query_args->wrapper;
419419
if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query, args, RUBY_UBF_IO, 0) == Qfalse) {
420420
/* an error occurred, we're not active anymore */
421-
MARK_CONN_INACTIVE(self);
422-
return rb_raise_mysql2_error(wrapper);
421+
wrapper->active_thread = Qnil;
422+
rb_raise_mysql2_error(wrapper);
423423
}
424424
return Qnil;
425425
}
@@ -448,7 +448,7 @@ static void *nogvl_do_result(void *ptr, char use_result) {
448448

449449
/* once our result is stored off, this connection is
450450
ready for another command to be issued */
451-
MARK_CONN_INACTIVE(self);
451+
wrapper->active_thread = Qnil;
452452

453453
return result;
454454
}
@@ -480,8 +480,8 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
480480
REQUIRE_CONNECTED(wrapper);
481481
if ((VALUE)rb_thread_call_without_gvl(nogvl_read_query_result, wrapper->client, RUBY_UBF_IO, 0) == Qfalse) {
482482
/* an error occurred, mark this connection inactive */
483-
MARK_CONN_INACTIVE(self);
484-
return rb_raise_mysql2_error(wrapper);
483+
wrapper->active_thread = Qnil;
484+
rb_raise_mysql2_error(wrapper);
485485
}
486486

487487
is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
@@ -493,7 +493,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
493493

494494
if (result == NULL) {
495495
if (mysql_errno(wrapper->client) != 0) {
496-
MARK_CONN_INACTIVE(self);
496+
wrapper->active_thread = Qnil;
497497
rb_raise_mysql2_error(wrapper);
498498
}
499499
/* no data and no error, so query was not a SELECT */
@@ -517,7 +517,7 @@ struct async_query_args {
517517
static VALUE disconnect_and_raise(VALUE self, VALUE error) {
518518
GET_CLIENT(self);
519519

520-
MARK_CONN_INACTIVE(self);
520+
wrapper->active_thread = Qnil;
521521
wrapper->connected = 0;
522522

523523
/* Invalidate the MySQL socket to prevent further communication.
@@ -588,7 +588,7 @@ static VALUE finish_and_mark_inactive(void *args) {
588588
result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
589589
mysql_free_result(result);
590590

591-
MARK_CONN_INACTIVE(self);
591+
wrapper->active_thread = Qnil;
592592
}
593593

594594
return Qnil;
@@ -1011,10 +1011,10 @@ static VALUE rb_mysql_client_ping(VALUE self) {
10111011
static VALUE rb_mysql_client_more_results(VALUE self)
10121012
{
10131013
GET_CLIENT(self);
1014-
if (mysql_more_results(wrapper->client) == 0)
1015-
return Qfalse;
1016-
else
1017-
return Qtrue;
1014+
if (mysql_more_results(wrapper->client) == 0)
1015+
return Qfalse;
1016+
else
1017+
return Qtrue;
10181018
}
10191019

10201020
/* call-seq:
@@ -1228,7 +1228,7 @@ static VALUE initialize_ext(VALUE self) {
12281228

12291229
if ((VALUE)rb_thread_call_without_gvl(nogvl_init, wrapper, RUBY_UBF_IO, 0) == Qfalse) {
12301230
/* TODO: warning - not enough memory? */
1231-
return rb_raise_mysql2_error(wrapper);
1231+
rb_raise_mysql2_error(wrapper);
12321232
}
12331233

12341234
wrapper->initialized = 1;

ext/mysql2/client.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,6 @@ typedef struct {
5959

6060
void rb_mysql_client_set_active_thread(VALUE self);
6161

62-
#define MARK_CONN_INACTIVE(conn) do {\
63-
wrapper->active_thread = Qnil; \
64-
} while(0)
65-
6662
#define GET_CLIENT(self) \
6763
mysql_client_wrapper *wrapper; \
6864
Data_Get_Struct(self, mysql_client_wrapper, wrapper);

ext/mysql2/statement.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ static VALUE intern_usec, intern_sec, intern_min, intern_hour, intern_day, inter
1111
if (!stmt_wrapper->stmt) { rb_raise(cMysql2Error, "Invalid statement handle"); } \
1212
if (stmt_wrapper->closed) { rb_raise(cMysql2Error, "Statement handle already closed"); }
1313

14-
1514
static void rb_mysql_stmt_mark(void * ptr) {
1615
mysql_stmt_wrapper *stmt_wrapper = ptr;
1716
if (!stmt_wrapper) return;
@@ -42,7 +41,6 @@ void decr_mysql2_stmt(mysql_stmt_wrapper *stmt_wrapper) {
4241
}
4342
}
4443

45-
4644
void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) {
4745
VALUE e;
4846
GET_CLIENT(stmt_wrapper->client);
@@ -71,7 +69,6 @@ void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) {
7169
rb_exc_raise(e);
7270
}
7371

74-
7572
/*
7673
* used to pass all arguments to mysql_stmt_prepare while inside
7774
* nogvl_prepare_statement_args
@@ -180,16 +177,6 @@ static void *nogvl_execute(void *ptr) {
180177
}
181178
}
182179

183-
static void *nogvl_stmt_store_result(void *ptr) {
184-
MYSQL_STMT *stmt = ptr;
185-
186-
if (mysql_stmt_store_result(stmt)) {
187-
return (void *)Qfalse;
188-
} else {
189-
return (void *)Qtrue;
190-
}
191-
}
192-
193180
static void set_buffer_for_string(MYSQL_BIND* bind_buffer, unsigned long *length_buffer, VALUE string) {
194181
int length;
195182

@@ -369,8 +356,7 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
369356
if (metadata == NULL) {
370357
if (mysql_stmt_errno(stmt) != 0) {
371358
// either CR_OUT_OF_MEMORY or CR_UNKNOWN_ERROR. both fatal.
372-
373-
MARK_CONN_INACTIVE(stmt_wrapper->client);
359+
wrapper->active_thread = Qnil;
374360
rb_raise_mysql2_stmt_error(stmt_wrapper);
375361
}
376362
// no data and no error, so query was not a SELECT
@@ -384,11 +370,11 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) {
384370
is_streaming = (Qtrue == rb_hash_aref(current, sym_stream));
385371
if (!is_streaming) {
386372
// recieve the whole result set from the server
387-
if (rb_thread_call_without_gvl(nogvl_stmt_store_result, stmt, RUBY_UBF_IO, 0) == Qfalse) {
373+
if (mysql_stmt_store_result(stmt)) {
388374
mysql_free_result(metadata);
389375
rb_raise_mysql2_stmt_error(stmt_wrapper);
390376
}
391-
MARK_CONN_INACTIVE(stmt_wrapper->client);
377+
wrapper->active_thread = Qnil;
392378
}
393379

394380
resultObj = rb_mysql_result_to_obj(stmt_wrapper->client, wrapper->encoding, current, metadata, self);

0 commit comments

Comments
 (0)