Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere Server - Programming » ODBC support


Calling ODBC functions from DllMain

Note that ODBC functions should not be called directly or indirectly from the DllMain function in a Windows Dynamic Link Library. The DllMain entry point function is intended to perform only simple initialization and termination tasks. Calling ODBC functions like SQLFreeHandle, SQLFreeConnect, and SQLFreeEnv can create deadlocks and circular dependencies.

The following code example illustrates a bad programming practice. When the Microsoft ODBC Driver Manager detects that the last access to the SQL Anywhere ODBC driver has completed, it will do a driver unload. When the SQL Anywhere ODBC driver shuts down, it stops any active threads. Thread termination results in a recursive thread detach call into DllMain. Since the call into DllMain is serialized, and a call is underway, the new thread detach call will never get started. The SQL Anywhere ODBC driver will wait forever for its threads to terminate and your application will hang.

    DWORD  fdwReason,
    LPVOID lpvReserved
    HANDLE      *handles;
    switch( fdwReason ) {
        /* do thread cleanup */
        handles = (HANDLE *) TlsGetValue( TlsIndex );
        if( handles != NULL )
            HENV        tls_henv;
            HDBC        tls_hdbc;
            tls_henv = (HENV) handles[0];
            tls_hdbc = (HDBC) handles[1];
            if( tls_hdbc != NULL )
                SQLFreeHandle( SQL_HANDLE_DBC, tls_hdbc );
            if( tls_henv != NULL )
                SQLFreeHandle( SQL_HANDLE_ENV, tls_henv );     
            handles[0] = NULL;
            handles[1] = NULL;
    return TRUE;        /* indicate success */

For more information, read the Microsoft white paper on Best Practices for Creating DLLs at [external link]