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 サーバー プログラミング » ODBC サポート

 

DllMain からの ODBC 関数の呼び出し

Windows ダイナミックリンクライブラリ内の DllMain 関数から直接的または間接的に ODBC 関数を呼び出さないでください。DllMain のエントリポイント関数は、簡単な初期化および終了処理のみを実行するためのものです。SQLFreeHandle、SQLFreeConnect、SQLFreeEnv などの ODBC 関数を呼び出した場合、デッドロックや循環依存が発生する可能性があります。

適切でないプログラミングコードの例を次に示します。Microsoft ODBC ドライバーマネージャーは、SQL Anywhere ODBC ドライバーへの最後のアクセスが完了したことを検出すると、ドライバーのアンロードを実行します。SQL Anywhere ODBC ドライバーが停止すると、アクティブなスレッドがすべて停止します。スレッドの終了の結果、DllMain への再帰的なスレッド detach 呼び出しが発生します。DllMain への呼び出しは直列化されていて、呼び出しが進行中であるため、新しいスレッド detach 呼び出しが開始されることはありません。SQL Anywhere ODBC ドライバーはスレッドが終了するまで永久に待機することになり、アプリケーションがハングします。



BOOL APIENTRY DllMain( HMODULE hinstDLL,
    DWORD  fdwReason,
    LPVOID lpvReserved
    )
{
    HANDLE      *handles;
    switch( fdwReason ) {
.
.
.
    case DLL_THREAD_DETACH:
        /* 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;
        }
        break;
.
.
.
    }
    return TRUE;        /* indicate success */
}

DLL を作成する際のベストプラクティスの詳細については、[external link] http://msdn.microsoft.com/en-us/windows/hardware/gg487379.aspx にある Microsoft のホワイトペーパーを参照してください。