This fixes a race condition, where SQLFreeStmt is called while the
connection is busy executing another statement. SC_set_prepared would see
that the connection is busy (CONN_EXECUTING), and not issue a DEALLOCATE
statement to free the prepared statement in the backend, leaking it.
SQLUSMALLINT Option)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
+ ConnectionClass *conn = NULL;
mylog("[SQLFreeStmt]");
+
+ if (stmt)
+ {
+ if (Option == SQL_DROP)
+ {
+ conn = stmt->hdbc;
+ if (conn)
+ ENTER_CONN_CS(conn);
+ }
+ else
+ ENTER_STMT_CS(stmt);
+ }
+
ret = PGAPI_FreeStmt(StatementHandle, Option);
+
+ if (stmt)
+ {
+ if (Option == SQL_DROP)
+ {
+ if (conn)
+ LEAVE_CONN_CS(conn);
+ }
+ else
+ LEAVE_STMT_CS(stmt);
+ }
+
return ret;
}
{
CSTR func = "SQLFreeHandle";
RETCODE ret;
+ StatementClass *stmt;
+ ConnectionClass *conn = NULL;
+
mylog("[[%s]]", func);
+
switch (HandleType)
{
case SQL_HANDLE_ENV:
ret = PGAPI_FreeConnect(Handle);
break;
case SQL_HANDLE_STMT:
+ stmt = (StatementClass *) Handle;
+
+ if (stmt)
+ {
+ conn = stmt->hdbc;
+ if (conn)
+ ENTER_CONN_CS(conn);
+ }
+
ret = PGAPI_FreeStmt(Handle, SQL_DROP);
+
+ if (conn)
+ LEAVE_CONN_CS(conn);
+
break;
case SQL_HANDLE_DESC:
ret = PGAPI_FreeDesc(Handle);