/*
* 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;
}