Remember by posting about a working informix driver for 3.x?
Well -- I guess I have an almost working Informix driver.
The driver loads, connects, and works fine until I let it idle for a while
and an idle handle gets closed. I get the following two lines in the log:
Notice: Done running scheduled proc acs_messaging_process_queue.
Notice: dbinit: closing idle handle in pool 'noacs_eoffice'
Once this happens, my next attempt to access the informix db pool fails.
The handle passed to OpenDb is bogus so handle->datasource is null or filled
with random garbage. My suspision is that CloseDb is freeing something
that it shouldn't but it's not obvious to me. (I only dable in C code).
I'm hoping someone resolved a similar problem when porting a AOS 2.x driver
to 3.x. Here are the OpenDb and CloseDb functions. any help would be greatly
appreciated.
---
/* OpenDb
*******************************************************************************
** Open a connection & initialise handle.
**
** Note that we don't use the `define_locked_fun' macro here, as at this
** point the uninitialised handle doesn't have a mutex to use!
*/
static int OpenDb(Ns_DbHandle *handle)
{
EXEC SQL BEGIN DECLARE SECTION;
char *dbname;
string *conn_name;
EXEC SQL END DECLARE SECTION;
static long gensym_counter = 0; /* Protected by gensym_mutex. */
int conn_id;
struct ius_state *ius_stuff;
Ns_Log(Notice, "Open");
if( !handle ) {
Ns_Log(Error, "Null handle.");
return (NS_ERROR);
}
Ns_Log(Notice,
"Connecting to datasource '%s' as user '%s' with password '%s'.",
denull(handle->datasource),
denull(handle->user),
denull(handle->password));
if( !handle->datasource ) {
Ns_Log(Error, "No datasource.");
return NS_ERROR;
}
dbname = strchr(handle->datasource, ':');
if( !dbname ) {
Ns_Log(Error, "Datasource doesn't contain a colon.");
return NS_ERROR;
}
dbname++; /* Skip the colon. */
/* Connections need SQL names. We just gensym them up using conn_id
** for a counter; we wrap at 2^31. The gensym op must be protected with
** a mutex.
*/
Ns_LockMutex(&gensym_mutex);
gensym_counter = (gensym_counter+1) & 0x3FFFFFFF;
conn_id = gensym_counter;
Ns_UnlockMutex(&gensym_mutex);
ius_stuff = Alloc(struct ius_state);
conn_name = ius_stuff->cname;
sprintf(conn_name, "ns%d", conn_id);
/* CONCURRENT TRANSACTION clause enables cross-thread transactions. */
EXEC SQL connect to :dbname as :conn_name with concurrent transaction;
handle->connection = (void*) ius_stuff;
/* Free cursors and their statements when they are closed. */
EXEC SQL set autofree;
/* Tell the database to allow SQL string literals to contain
** newline chars. What bunch of brain-dead pinheads designed
** this system?
*/
/* Commented out because it was causing an error (probably obsolete
**
** EXEC SQL EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');
*/
/* Make the connection dormant so it's not associated
** with a particular thread.
*/
EXEC SQL set connection :conn_name dormant;
/* Success. */
Ns_InitializeMutex(&ius_stuff->mutex);
handle->connected = 1;
handle->fetchingRows = 0;
ius_stuff->rowbuf = NULL;
return NS_OK;
/* Failure. Clean up and return. */
sql_err:
report_xcptn(handle);
Free(ius_stuff);
handle->connection = NULL;
return NS_ERROR;
}
/* CloseDb
*******************************************************************************
** Close a connection and free up related resources.
**
** Note that we don't use `define_locked_fun', as we don't have a connection
** to disconnect after the core function has done its job.
*/
static int CloseDb(Ns_DbHandle *handle)
{
struct ius_state *state;
EXEC SQL BEGIN DECLARE SECTION;
string *conn_name;
EXEC SQL END DECLARE SECTION;
int set_dormant = 0; /* Advises sql_err error handler. */
Ns_Log(Notice, "CloseDb");
if( !handle ) { /* Error checks */
Ns_Log(Error, "CloseDb -- Null handle.");
return NS_ERROR;
}
if( !handle->connected || !handle->connection ) {
Ns_Log(Error, "CloseDb -- handle not connected.");
return NS_ERROR;
}
state = (struct ius_state*) handle->connection;
conn_name = state->cname;
Ns_LockMutex(& state->mutex); /* Lock. */
EXEC SQL set connection :conn_name; /* Connect. */
set_dormant = 1;
EXEC SQL disconnect :conn_name; /* Close the connection. */
set_dormant = 0;
handle->connected = 0; /* Clear out handle. */
if( handle->datasource ) { Free(handle->datasource); handle->datasource =
NULL; }
if( handle->user ) { Free(handle->user); handle->user =
NULL; }
if( handle->password ) { Free(handle->password); handle->password =
NULL; }
Ns_UnlockMutex(& state->mutex); /* Unlock & free state. */
Ns_DestroyMutex(& state->mutex);
free_rowbuf(handle);
Free(state); handle->connection = NULL;
return NS_OK;
sql_err:
report_xcptn(handle);
if( set_dormant ) {
EXEC SQL set connection :conn_name dormant;
}
Ns_UnlockMutex(& state->mutex); /* Unlock. */
return NS_ERROR;
}
---
------
Keith Paskett [EMAIL PROTECTED]
Space Dynamics Laboratory PGP or GPG encrypted mail preferred
1695 North Research Parkway 435-797-4195
Logan, Utah 84341