@@ -7,7 +7,8 @@ static VALUE intern_usec, intern_sec, intern_min, intern_hour, intern_day, inter
7
7
8
8
#define GET_STATEMENT (self ) \
9
9
mysql_stmt_wrapper *stmt_wrapper; \
10
- Data_Get_Struct(self, mysql_stmt_wrapper, stmt_wrapper);
10
+ Data_Get_Struct(self, mysql_stmt_wrapper, stmt_wrapper); \
11
+ if (!stmt_wrapper->stmt) { rb_raise(cMysql2Error, "Invalid statement handle"); }
11
12
12
13
13
14
static void rb_mysql_stmt_mark (void * ptr ) {
@@ -17,6 +18,15 @@ static void rb_mysql_stmt_mark(void * ptr) {
17
18
rb_gc_mark (stmt_wrapper -> client );
18
19
}
19
20
21
+ static void * nogvl_stmt_close (void * ptr ) {
22
+ mysql_stmt_wrapper * stmt_wrapper = (mysql_stmt_wrapper * )ptr ;
23
+ if (stmt_wrapper -> stmt ) {
24
+ mysql_stmt_close (stmt_wrapper -> stmt );
25
+ stmt_wrapper -> stmt = NULL ;
26
+ }
27
+ return NULL ;
28
+ }
29
+
20
30
static void rb_mysql_stmt_free (void * ptr ) {
21
31
mysql_stmt_wrapper * stmt_wrapper = (mysql_stmt_wrapper * )ptr ;
22
32
decr_mysql2_stmt (stmt_wrapper );
@@ -26,7 +36,7 @@ void decr_mysql2_stmt(mysql_stmt_wrapper *stmt_wrapper) {
26
36
stmt_wrapper -> refcount -- ;
27
37
28
38
if (stmt_wrapper -> refcount == 0 ) {
29
- mysql_stmt_close (stmt_wrapper -> stmt );
39
+ nogvl_stmt_close (stmt_wrapper );
30
40
xfree (stmt_wrapper );
31
41
}
32
42
}
@@ -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