Skip to Content.
Sympa Menu

freetds - Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT freetds.org>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE
  • Date: Mon, 14 Jan 2008 01:34:32 -0500

Frediano Ziglio wrote:
> Also it
> seems that in some different systems signal are handled in a slightly
> different way. That is
> - query is sent, state is set to TDS_READING
> - select/poll stops
> - signal is caught, SQLCancel is called

Who catches the signal? I hope it's the application.

I don't know the proper treatment of signals in an ODBC application, but
I'm pretty sure SQLCancel shouldn't be called in a signal handler. The
handler doesn't have enough information to know whether that's the right
thing to do.

I think all the signal handler can do is record the fact that a signal was
caught in a more-or-less global variable. When the called function
returns an error -- e.g. a timeout on reads -- the app can then decide
whether or not to call SQLCancel.

> - cancel token is sent, in_cancel get 1, current_statement is reset

By whom? It's too soon....

> - select/poll stop with EINTR error
> - interrupt is call (which do nothing)

The driver could steer here. We could add a property to the FreeTDS ODBC
driver that would let the app tell the driver how to treat EINTR on reads.


Default behavior probably should be to return TDS_INT_CANCEL if sock_errno
== TDSSOCK_EINTR.

Writes are a different matter. There's no cancel packet to send. The
library should ignore the signal and let the application handle it.

> - tds_select returns 0
> - tdserror(TDSETIME) is called
> - odbc_errmsg_handler close connection cause current_statement is
> NULL...

In sum, treat EINTR like an early timeout:

1. Don't catch the signal. Let the app do it.
2. Let odbc_errmsg_handler return TDS_INT_TIMEOUT to tdserror(); let
tdserror() send the cancel packet.
3. Return control to the application with a timeout error.

When control returns to the application, he'll have a failed call, a
connection that's probably OK but might be dead, and evidence that a
signal was caught.

There's an expression in English, "to put two and two together", meaning
to come to the obvious conclusion. The application puts two and two
together, decides the signal caused the timeout, sees the state of the
connection, and decides what to do.

HTH.

--jkl




Archive powered by MHonArc 2.6.24.

Top of Page