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: "ZIGLIO, Frediano, VF-IT" <Frediano.Ziglio AT vodafone.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE
  • Date: Mon, 14 Jan 2008 10:05:58 +0100

>
> 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.
>


We correctly do not catches signals. Signals are a nightmare using
threads so I prefer not having to handle them. ODBC specification say
that there are 4 cancel types:
1- inline, call a statement and cancel data results, correctly supported
2- asyncronous, not still supported so no problem
3- cancel when sending long data (SQL_NEED_DATA). Never requested...
4- cancel from another thread
Cancellation on signal is not documented however:
- windows/dos does not have a signal handling working/used like *nix
systems
- ctlib specification require ct_cancel called in signal (supported, see
cancel test)

> 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.
>

As said I wouldn't handle signals in FreeTDS. The application can always
overwrite signals. Currently there is an exeption where our library
ignore SIGPIPE but only on system where send/write/recv/read do not
support ignoring signals (that is very old systems where probably thread
are not supported or rarely used).

> > - cancel token is sent, in_cancel get 1, current_statement is reset
>
> By whom? It's too soon....
>

By SQLCancel (tds_send_cancel send token and set in_cancel, SQLCancel
reset current statement)

> > - 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.
>

So, say continue on EINTR... yes seems ok. However int_handler is not
used only for interrupts... or to be correct is used mainly for dblib
1-second polling. Every 1 seconds a timeout is generated and handled by
dblib. I don't like dblib polling way (personally I hate polling, if I
know a query can take very long I prefer so not disturb system scheduler
every second!).

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

So close the connection ??

> 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.

Mmmm... however some implementations does not call tdserror so not
sending cancel packet on signal handler make wait undefinitely.

> 3. Return control to the application with a timeout error.
>

In this case standard reply is HY008, statement cancelled.

> 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.
>

Attached an output mixed with system trace and tds dump on a system that
get EINTR (I tested under 2 Linux systems... one returns EINTR while the
other seems to ignore them...).

freddy77

Attachment: cancel.html.gz
Description: cancel.html.gz




Archive powered by MHonArc 2.6.24.

Top of Page