MYSQL_RES *do_mysql_cCommand_execute_async(VALUE self, VALUE connection, MYSQL *db, VALUE query) { int retval; if ((retval = mysql_ping(db)) && mysql_errno(db) == CR_SERVER_GONE_ERROR) { do_mysql_full_connect(connection, db); } struct timeval start; const char *str = rb_str_ptr_readonly(query); long len = rb_str_len(query); gettimeofday(&start, NULL); retval = mysql_send_query(db, str, len); CHECK_AND_RAISE(retval, query); int socket_fd = db->net.fd; fd_set rset; while (1) { FD_ZERO(&rset); FD_SET(socket_fd, &rset); retval = rb_thread_select(socket_fd + 1, &rset, NULL, NULL, NULL); if (retval < 0) { rb_sys_fail(0); } if (retval == 0) { continue; } if (db->status == MYSQL_STATUS_READY) { break; } } retval = mysql_read_query_result(db); CHECK_AND_RAISE(retval, query); data_objects_debug(connection, query, &start); MYSQL_RES *result = mysql_store_result(db); if (!result) { CHECK_AND_RAISE(mysql_errno(db), query); } return result; }
/* * even though we did rb_thread_select before calling this, a large * response can overflow the socket buffers and cause us to eventually * block while calling mysql_read_query_result */ static VALUE nogvl_read_query_result(void *ptr) { MYSQL * client = ptr; my_bool res = mysql_read_query_result(client); return res == 0 ? Qtrue : Qfalse; }
/* * even though we did rb_thread_select before calling this, a large * response can overflow the socket buffers and cause us to eventually * block while calling mysql_read_query_result */ static void *nogvl_read_query_result(void *ptr) { MYSQL * client = ptr; my_bool res = mysql_read_query_result(client); return (void *)(res == 0 ? Qtrue : Qfalse); }