[freetds] cancel and timeout

Thompson, Bill D (London) bill_d_thompson at ml.com
Fri Jan 21 04:42:57 EST 2005


I recently tested the dbsetinterrupt() functionality and it behaves
exactly like Sybase dblibrary AFAICT.


-----Original Message-----
From: freetds-bounces at lists.ibiblio.org
[mailto:freetds-bounces at lists.ibiblio.org] On Behalf Of James K. Lowden
Sent: 21 January 2005 03:37
To: FreeTDS Development Group
Subject: Re: [freetds] cancel and timeout

On Thu, 20 Jan 2005 17:11:12 -0000, "Thompson, Bill D (London)"
<bill_d_thompson at ml.com> wrote:
> > Timeout
> > -------
> > Now if a timeout (now query_timeout) a query_timeout_func it's
> I
> > removed chkintr and hndlintr (one function it's sufficient).
> > query_start_time it's use for global time counting. I don't know if
> > query timeout on dblib works as expected. Perhaps even SQLFetch or
> > similar need setting timeout.
> I think there are two functions because this then mirrors the
> interrupt handlers.  

Thanks for tackling this, Freddy.  

I think Bill means:

	void dbsetinterrupt(dbproc, chkintr, hndlintr)

	DBPROCESS     *dbproc;
	int           (*chkintr)();
	int           (*hndlintr)();


Note the comment:

"DB-Library does non-blocking reads from the server. While waiting for a
read from the server, it will call the chkintr() function to see if an
interrupt is pending. If chkintr() returns TRUE and a handler has been
installed as the hndlintr() for dbsetinterrupt, hndlintr() will be

That's not how dblib_query_timeout() is currently coded.  chkintr should
be called periodically from within src/tds/net.c::goodread() until

1.  the server sends data, or
2.  the query_timeout expires.

goodread() calls hndlintr after the timeout.  It should call it while
counting down to the timeout.  How often?  The docs don't say.  They say
they (Sybase) do non-blocking I/O, implying a busy wait.  I think it
be OK to call select(2) with a timeout of, say, 100 ms (blocking), then
call hndlintr, then busyfunc, then deduct 100 ms from query_timeout, and
call select(2) again.  Something like:

	for (ti = selecttimeout; 
		retcode = select(tds->s + 1, &fds, NULL, NULL, ti);
		ti.tv_usec -= 100) 
		if (retcode < 0) {
			/* error */
		if (retcode > 0) {
			break; /* data ready: read */
		assert(retcode == 0); /* partial timeout */
		if (ti.tv_usec < 0) {
			ti.tv_usec += 1000;

		if (ti.tv_sec < 0) break; /* really timed out */

		if ((*tds->chkintr)())
		if (tds->busyfunc)
	len = READSOCKET(tds->s, buf + got, buflen);
	if (tds->idlefunc)

These may also be interesting:


"idlefunc() will be automatically called whenever DB-Library has
reading output from the server."


"automatically called whenever DB-Library is reading or waiting to read
output from the server."

FreeTDS mailing list
FreeTDS at lists.ibiblio.org
If you are not an intended recipient of this e-mail, please notify the sender, delete it and do not read, act upon, print, disclose, copy, retain or redistribute it. Click here for important additional terms relating to this e-mail.     http://www.ml.com/email_terms/ 

More information about the FreeTDS mailing list