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

SAP Sybase SQL Anywhere 16.0 » SQL Anywhere サーバ プログラミング » ODBC サポート

 

Windows DllMain 関数の考慮事項

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 )
        {
            SQLHENV     tls_henv;
            SQLHDBC     tls_hdbc;
            
            tls_henv = (SQLHENV) handles[0];
            tls_hdbc = (SQLHDBC) 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 */
}

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