@@ -79,35 +79,73 @@ VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap) {
79
79
80
80
#define NOGVL_DBCALL (_dbfunction , _client ) ( \
81
81
(RETCODE)rb_thread_blocking_region( \
82
- (rb_blocking_function_t*)nogvl_ ## _dbfunction, _client, \
82
+ (rb_blocking_function_t*)_dbfunction, _client, \
83
83
(rb_unblock_function_t*)dbcancel_ubf, _client ) \
84
84
)
85
85
86
+ static void dbcancel_ubf (DBPROCESS * client ) {
87
+ GET_CLIENT_USERDATA (client );
88
+ dbcancel (client );
89
+ userdata -> dbcancel_sent = 1 ;
90
+ userdata -> dbsql_sent = 0 ;
91
+ }
92
+
93
+ static void nogvl_setup (DBPROCESS * client ) {
94
+ GET_CLIENT_USERDATA (client );
95
+ userdata -> nonblocking = 1 ;
96
+ }
97
+
98
+ static void nogvl_cleanup (DBPROCESS * client ) {
99
+ GET_CLIENT_USERDATA (client );
100
+ userdata -> nonblocking = 0 ;
101
+ /*
102
+ Now that the blocking operation is done, we can finally throw any
103
+ exceptions based on errors from SQL Server.
104
+ */
105
+ if (userdata -> nonblocking_error .is_set ) {
106
+ userdata -> nonblocking_error .is_set = 0 ;
107
+ rb_tinytds_raise_error (client ,
108
+ userdata -> nonblocking_error .cancel ,
109
+ & userdata -> nonblocking_error .error ,
110
+ & userdata -> nonblocking_error .source ,
111
+ userdata -> nonblocking_error .severity ,
112
+ userdata -> nonblocking_error .dberr ,
113
+ userdata -> nonblocking_error .oserr );
114
+ }
115
+ }
116
+
86
117
static RETCODE nogvl_dbsqlok (DBPROCESS * client ) {
87
118
int retcode = FAIL ;
88
119
GET_CLIENT_USERDATA (client );
89
- retcode = dbsqlok (client );
120
+ nogvl_setup (client );
121
+ retcode = NOGVL_DBCALL (dbsqlok , client );
122
+ nogvl_cleanup (client );
90
123
userdata -> dbsqlok_sent = 1 ;
91
124
return retcode ;
92
125
}
93
126
94
127
static RETCODE nogvl_dbsqlexec (DBPROCESS * client ) {
95
- return dbsqlexec (client );
128
+ int retcode = FAIL ;
129
+ nogvl_setup (client );
130
+ retcode = NOGVL_DBCALL (dbsqlexec , client );
131
+ nogvl_cleanup (client );
132
+ return retcode ;
96
133
}
97
134
98
135
static RETCODE nogvl_dbresults (DBPROCESS * client ) {
99
- return dbresults (client );
136
+ int retcode = FAIL ;
137
+ nogvl_setup (client );
138
+ retcode = NOGVL_DBCALL (dbresults , client );
139
+ nogvl_cleanup (client );
140
+ return retcode ;
100
141
}
101
142
102
143
static RETCODE nogvl_dbnextrow (DBPROCESS * client ) {
103
- return dbnextrow (client );
104
- }
105
-
106
- static void dbcancel_ubf (DBPROCESS * client ) {
107
- GET_CLIENT_USERDATA (client );
108
- dbcancel (client );
109
- userdata -> dbcancel_sent = 1 ;
110
- userdata -> dbsql_sent = 0 ;
144
+ int retcode = FAIL ;
145
+ nogvl_setup (client );
146
+ retcode = NOGVL_DBCALL (dbnextrow , client );
147
+ nogvl_cleanup (client );
148
+ return retcode ;
111
149
}
112
150
113
151
// Lib Backend (Helpers)
@@ -118,7 +156,7 @@ static RETCODE rb_tinytds_result_dbresults_retcode(VALUE self) {
118
156
RETCODE db_rc ;
119
157
ruby_rc = rb_ary_entry (rwrap -> dbresults_retcodes , rwrap -> number_of_results );
120
158
if (NIL_P (ruby_rc )) {
121
- db_rc = NOGVL_DBCALL ( dbresults , rwrap -> client );
159
+ db_rc = nogvl_dbresults ( rwrap -> client );
122
160
ruby_rc = INT2FIX (db_rc );
123
161
rb_ary_store (rwrap -> dbresults_retcodes , rwrap -> number_of_results , ruby_rc );
124
162
} else {
@@ -130,7 +168,7 @@ static RETCODE rb_tinytds_result_dbresults_retcode(VALUE self) {
130
168
static RETCODE rb_tinytds_result_ok_helper (DBPROCESS * client ) {
131
169
GET_CLIENT_USERDATA (client );
132
170
if (userdata -> dbsqlok_sent == 0 ) {
133
- userdata -> dbsqlok_retcode = NOGVL_DBCALL ( dbsqlok , client );
171
+ userdata -> dbsqlok_retcode = nogvl_dbsqlok ( client );
134
172
}
135
173
return userdata -> dbsqlok_retcode ;
136
174
}
@@ -373,7 +411,7 @@ static VALUE rb_tinytds_result_each(int argc, VALUE * argv, VALUE self) {
373
411
/* Create rows for this result set. */
374
412
unsigned long rowi = 0 ;
375
413
VALUE result = rb_ary_new ();
376
- while (NOGVL_DBCALL ( dbnextrow , rwrap -> client ) != NO_MORE_ROWS ) {
414
+ while (nogvl_dbnextrow ( rwrap -> client ) != NO_MORE_ROWS ) {
377
415
VALUE row = rb_tinytds_result_fetch_row (self , timezone , symbolize_keys , as_array );
378
416
if (cache_rows )
379
417
rb_ary_store (result , rowi , row );
@@ -406,7 +444,7 @@ static VALUE rb_tinytds_result_each(int argc, VALUE * argv, VALUE self) {
406
444
} else {
407
445
// If we do not find results, side step the rb_tinytds_result_dbresults_retcode helper and
408
446
// manually populate its memoized array while nullifing any memoized fields too before loop.
409
- dbresults_rc = NOGVL_DBCALL ( dbresults , rwrap -> client );
447
+ dbresults_rc = nogvl_dbresults ( rwrap -> client );
410
448
rb_ary_store (rwrap -> dbresults_retcodes , rwrap -> number_of_results , INT2FIX (dbresults_rc ));
411
449
rb_ary_store (rwrap -> fields_processed , rwrap -> number_of_results , Qnil );
412
450
}
@@ -466,10 +504,10 @@ static VALUE rb_tinytds_result_insert(VALUE self) {
466
504
rb_tinytds_result_cancel_helper (rwrap -> client );
467
505
VALUE identity = Qnil ;
468
506
dbcmd (rwrap -> client , rwrap -> cwrap -> identity_insert_sql );
469
- if (NOGVL_DBCALL ( dbsqlexec , rwrap -> client ) != FAIL
470
- && NOGVL_DBCALL ( dbresults , rwrap -> client ) != FAIL
507
+ if (nogvl_dbsqlexec ( rwrap -> client ) != FAIL
508
+ && nogvl_dbresults ( rwrap -> client ) != FAIL
471
509
&& DBROWS (rwrap -> client ) != FAIL ) {
472
- while (NOGVL_DBCALL ( dbnextrow , rwrap -> client ) != NO_MORE_ROWS ) {
510
+ while (nogvl_dbnextrow ( rwrap -> client ) != NO_MORE_ROWS ) {
473
511
int col = 1 ;
474
512
BYTE * data = dbdata (rwrap -> client , col );
475
513
DBINT data_len = dbdatlen (rwrap -> client , col );
0 commit comments