Skip to content

Commit

Permalink
Introduce CS_INTERRUPT_CB and corresponding return values: CS_INT_*.
Browse files Browse the repository at this point in the history
Define CS_INTERRUPT_CB's numeric value alongside other CS_*_CBs';
start a new 94xx range to avoid confusion with properties.
(Sybase/SAP ctlib has no such callback.)  Allow specification on
either the connection or the context level as usual, with the help of
a shim installed on demand to minimize interference with tds_select's
optimization for the no-handler case.  For CS_INT_*, copy TDS_INT_*
and confirm their equality at compile time as with CS_NULLTERM et al.

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
  • Loading branch information
ucko committed Dec 20, 2024
1 parent 7499210 commit 4aef5d0
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/cspublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ extern "C"
typedef CS_RETCODE(*CS_CSLIBMSG_FUNC) (CS_CONTEXT *, CS_CLIENTMSG *);
typedef CS_RETCODE(*CS_CLIENTMSG_FUNC) (CS_CONTEXT *, CS_CONNECTION *, CS_CLIENTMSG *);
typedef CS_RETCODE(*CS_SERVERMSG_FUNC) (CS_CONTEXT *, CS_CONNECTION *, CS_SERVERMSG *);
typedef CS_RETCODE(*CS_INTERRUPT_FUNC) (CS_CONNECTION *);


#define CS_IODATA TDS_STATIC_CAST(CS_INT, 1600)
Expand Down Expand Up @@ -437,6 +438,7 @@ enum
#define CS_SECSESSION_CB 8
#define CS_SIGNAL_CB 100
#define CS_MESSAGE_CB 9119
#define CS_INTERRUPT_CB 9400

/* string types */
#define CS_NULLTERM -9
Expand Down Expand Up @@ -773,6 +775,11 @@ enum
#define CS_SERVERMSG_TYPE 4701
#define CS_ALLMSG_TYPE 4702

/* CS_INTERRUPT_CB return values */
#define CS_INT_CONTINUE 1
#define CS_INT_CANCEL 2
#define CS_INT_TIMEOUT 3

CS_RETCODE cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT * destfmt, CS_VOID * destdata,
CS_INT * resultlen);
CS_RETCODE cs_ctx_alloc(CS_INT version, CS_CONTEXT ** ctx);
Expand Down
3 changes: 3 additions & 0 deletions include/ctlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ struct _cs_context
CS_CSLIBMSG_FUNC _cslibmsg_cb;
CS_CLIENTMSG_FUNC _clientmsg_cb;
CS_SERVERMSG_FUNC _servermsg_cb;
CS_INTERRUPT_FUNC _interrupt_cb;
/* code changes start here - CS_CONFIG - 01*/
void *userdata;
int userdata_len;
Expand Down Expand Up @@ -190,6 +191,7 @@ struct _cs_connection
TDSSOCKET *tds_socket;
CS_CLIENTMSG_FUNC _clientmsg_cb;
CS_SERVERMSG_FUNC _servermsg_cb;
CS_INTERRUPT_FUNC _interrupt_cb;
void *userdata;
int userdata_len;
CS_LOCALE *locale;
Expand Down Expand Up @@ -380,6 +382,7 @@ typedef union
*/
TDSRET _ct_handle_server_message(const TDSCONTEXT * ctxptr, TDSSOCKET * tdsptr, TDSMESSAGE * msgptr);
int _ct_handle_client_message(const TDSCONTEXT * ctxptr, TDSSOCKET * tdsptr, TDSMESSAGE * msgptr);
int _ct_handle_interrupt(void * ptr);
TDS_SERVER_TYPE _ct_get_server_type(TDSSOCKET *tds, int datatype);
int _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, CS_INT offset);
int _ct_get_client_type(const TDSCOLUMN *col, bool describe);
Expand Down
1 change: 1 addition & 0 deletions include/freetds/tds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,7 @@ typedef struct tds_multiple
/* forward declaration */
typedef struct tds_context TDSCONTEXT;
typedef int (*err_handler_t) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
typedef int (*int_handler_t) (void *);

struct tds_context
{
Expand Down
12 changes: 12 additions & 0 deletions src/ctlib/ct.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ ct_callback(CS_CONTEXT * ctx, CS_CONNECTION * con, CS_INT action, CS_INT type, C
case CS_SERVERMSG_CB:
out_func = (CS_VOID *) (con ? con->_servermsg_cb : ctx->_servermsg_cb);
break;
case CS_INTERRUPT_CB:
out_func = (CS_VOID *) (con ? con->_interrupt_cb
: ctx->_interrupt_cb);
break;
default:
_ctclient_msg(ctx, con, "ct_callback()", 1, 1, 1, 5, "%d, %s", type, "type");
return CS_FAIL;
Expand Down Expand Up @@ -389,6 +393,14 @@ ct_callback(CS_CONTEXT * ctx, CS_CONNECTION * con, CS_INT action, CS_INT type, C
else
ctx->_servermsg_cb = (CS_SERVERMSG_FUNC) funcptr;
break;
case CS_INTERRUPT_CB:
/* install shim on demand */
ctx->tds_ctx->int_handler = _ct_handle_interrupt;
if (con)
con->_interrupt_cb = (CS_INTERRUPT_FUNC) funcptr;
else
ctx->_interrupt_cb = (CS_INTERRUPT_FUNC) funcptr;
break;
default:
_ctclient_msg(ctx, con, "ct_callback()", 1, 1, 1, 5, "%d, %s", type, "type");
return CS_FAIL;
Expand Down
18 changes: 18 additions & 0 deletions src/ctlib/ctutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ TEST_EQUAL(t12,CS_COMPUTEFMT_RESULT,TDS_COMPUTEFMT_RESULT);
TEST_EQUAL(t13,CS_ROWFMT_RESULT,TDS_ROWFMT_RESULT);
TEST_EQUAL(t14,CS_MSG_RESULT,TDS_MSG_RESULT);
TEST_EQUAL(t15,CS_DESCRIBE_RESULT,TDS_DESCRIBE_RESULT);
TEST_EQUAL(t16,CS_INT_CONTINUE,TDS_INT_CONTINUE);
TEST_EQUAL(t17,CS_INT_CANCEL,TDS_INT_CANCEL);
TEST_EQUAL(t18,CS_INT_TIMEOUT,TDS_INT_TIMEOUT);

#define TEST_ATTRIBUTE(t,sa,fa,sb,fb) \
TDS_COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && TDS_OFFSET(sa,fa) == TDS_OFFSET(sb,fb))
Expand Down Expand Up @@ -161,6 +164,21 @@ _ct_handle_client_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG
return TDS_INT_CANCEL;
}

/*
* interrupt handler, installed on demand to avoid gratuitously interfering
* with tds_select's optimization for the no-handler case */
int
_ct_handle_interrupt(void * ptr)
{
CS_CONNECTION *con = (CS_CONNECTION *) ptr;
if (con->_interrupt_cb)
return (*con->_interrupt_cb)(con);
else if (con->ctx->_interrupt_cb)
return (*con->ctx->_interrupt_cb)(con);
else
return TDS_INT_CONTINUE;
}

/* message handler */
TDSRET
_ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAGE * msg)
Expand Down

0 comments on commit 4aef5d0

Please sign in to comment.