@@ -17,6 +17,15 @@ static void rb_mysql_stmt_mark(void * ptr) {
17
17
rb_gc_mark (stmt_wrapper -> client );
18
18
}
19
19
20
+ static void * nogvl_stmt_close (void * ptr ) {
21
+ mysql_stmt_wrapper * stmt_wrapper = (mysql_stmt_wrapper * )ptr ;
22
+ if (stmt_wrapper -> closed == 0 ) {
23
+ mysql_stmt_close (stmt_wrapper -> stmt );
24
+ stmt_wrapper -> closed = 1 ;
25
+ }
26
+ return NULL ;
27
+ }
28
+
20
29
static void rb_mysql_stmt_free (void * ptr ) {
21
30
mysql_stmt_wrapper * stmt_wrapper = (mysql_stmt_wrapper * )ptr ;
22
31
decr_mysql2_stmt (stmt_wrapper );
@@ -26,7 +35,7 @@ void decr_mysql2_stmt(mysql_stmt_wrapper *stmt_wrapper) {
26
35
stmt_wrapper -> refcount -- ;
27
36
28
37
if (stmt_wrapper -> refcount == 0 ) {
29
- mysql_stmt_close (stmt_wrapper -> stmt );
38
+ nogvl_stmt_close (stmt_wrapper );
30
39
xfree (stmt_wrapper );
31
40
}
32
41
}
@@ -94,6 +103,7 @@ VALUE rb_mysql_stmt_new(VALUE rb_client, VALUE sql) {
94
103
rb_stmt = Data_Make_Struct (cMysql2Statement , mysql_stmt_wrapper , rb_mysql_stmt_mark , rb_mysql_stmt_free , stmt_wrapper );
95
104
{
96
105
stmt_wrapper -> client = rb_client ;
106
+ stmt_wrapper -> closed = 0 ;
97
107
stmt_wrapper -> refcount = 1 ;
98
108
stmt_wrapper -> stmt = NULL ;
99
109
}
@@ -442,6 +452,19 @@ static VALUE rb_mysql_stmt_affected_rows(VALUE self) {
442
452
return ULL2NUM (affected );
443
453
}
444
454
455
+ /* call-seq:
456
+ * stmt.close
457
+ *
458
+ * Explicitly closing this will free up server resources immediately rather
459
+ * than waiting for the garbage collector. Useful if you're managing your
460
+ * own prepared statement cache.
461
+ */
462
+ static VALUE rb_mysql_stmt_close (VALUE self ) {
463
+ GET_STATEMENT (self );
464
+ rb_thread_call_without_gvl (nogvl_stmt_close , stmt_wrapper , RUBY_UBF_IO , 0 );
465
+ return Qnil ;
466
+ }
467
+
445
468
void init_mysql2_statement () {
446
469
cMysql2Statement = rb_define_class_under (mMysql2 , "Statement" , rb_cObject );
447
470
@@ -451,6 +474,7 @@ void init_mysql2_statement() {
451
474
rb_define_method (cMysql2Statement , "fields" , fields , 0 );
452
475
rb_define_method (cMysql2Statement , "last_id" , rb_mysql_stmt_last_id , 0 );
453
476
rb_define_method (cMysql2Statement , "affected_rows" , rb_mysql_stmt_affected_rows , 0 );
477
+ rb_define_method (cMysql2Statement , "close" , rb_mysql_stmt_close , 0 );
454
478
455
479
sym_stream = ID2SYM (rb_intern ("stream" ));
456
480
0 commit comments