/* * call-seq: * conn.block( [ timeout ] ) -> Boolean * * Blocks until the server is no longer busy, or until the * optional _timeout_ is reached, whichever comes first. * _timeout_ is measured in seconds and can be fractional. * * Returns +false+ if _timeout_ is reached, +true+ otherwise. * * If +true+ is returned, +conn.is_busy+ will return +false+ * and +conn.get_result+ will not block. */ static VALUE pgconn_block(int argc, VALUE *argv, VALUE self) { PGconn *conn = get_pgconn(self); int sd = PQsocket(conn); int ret; struct timeval timeout; struct timeval *ptimeout = NULL; VALUE timeout_in; double timeout_sec; fd_set sd_rset; if (rb_scan_args(argc, argv, "01", &timeout_in) == 1) { timeout_sec = NUM2DBL(timeout_in); timeout.tv_sec = (long)timeout_sec; timeout.tv_usec = (long)((timeout_sec - (long)timeout_sec) * 1e6); ptimeout = &timeout; } PQconsumeInput(conn); while(PQisBusy(conn)) { FD_ZERO(&sd_rset); FD_SET(sd, &sd_rset); ret = rb_thread_select(sd+1, &sd_rset, NULL, NULL, ptimeout); /* if select() times out, return false */ if(ret == 0) return Qfalse; PQconsumeInput(conn); } return Qtrue; }