Add locking to SQLFreeStmt and SQLFreeHandle.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 20 Feb 2014 07:09:47 +0000 (09:09 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 20 Feb 2014 07:09:47 +0000 (09:09 +0200)
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.

odbcapi.c
odbcapi30.c

index fc124d5b6289a65f293a5a8910d5de18ebca8791..efcd480fa46948a31f45678b079db5a9812c74bd 100644 (file)
--- a/odbcapi.c
+++ b/odbcapi.c
@@ -455,9 +455,36 @@ SQLFreeStmt(HSTMT StatementHandle,
            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;
 }
 
index 16288bb72657dc3a77485a357468ed600aae636a..4a99a4e6908a04d6715a2140247f4223365f657c 100644 (file)
@@ -239,7 +239,11 @@ SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
 {
    CSTR    func = "SQLFreeHandle";
    RETCODE     ret;
+   StatementClass *stmt;
+   ConnectionClass *conn = NULL;
+
    mylog("[[%s]]", func);
+
    switch (HandleType)
    {
        case SQL_HANDLE_ENV:
@@ -249,7 +253,20 @@ SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
            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);