Multithreading Issues in the Adapter and Client Applications
Because the ODBC Driver Manager is thread-safe, the WMI ODBC adapter is inherently thread-safe.
Note For more information about support or requirements for installation on a specific operating system, see Operating System Availability of WMI Components.
The only exception to the WMI ODBC adapter being thread-safe, is when an SQLCancel function is invoked while synchronously executing the hStmt statement handle object from a different thread. The ODBC Driver Manager uses critical sections (nonreentrant pieces of code) on the hEnvs environment handle, hDbcs connection handle, and hStmt handle to guarantee synchronous operation on these objects.
An action on one of these objects causes the ODBC Driver Manager to enter a critical section for that object. In the case of SQLCancel, the ODBC Driver Manager enters a cancel-in-progress critical section. This prevents SQLCancel from being reentered before the first SQLCancel function call is completed. The adapter's SQLCancel function is then invoked.
If there is no simultaneous action on the statement handle, the SQLCancel function is treated as an SQLFreeStmt function with an SQL_CLOSE option. The adapter returns SQL_SUCCESS_WITH_INFO with a SQLSTATE of 01S05. This causes the ODBC Driver Manager to return SQL_SUCCESS to the application.
If there was simultaneous action on the statement handle, the return code from the original thread's ODBC function determines if the SQLCancel function was successful.
The adapter's SQLCancel function is implemented as follows:
- In the adapter, each statement has a critical section.
- This critical section is entered on all ODBC functions that take a statement handle (except SQLCancel), and is left upon exit.
- The SQLCancel code inspects this critical section to determine if the section has been entered (nonzero owning thread). This is the test for determining if an SQLFreeStmt function with an SQL_CLOSE option must be called.
- If there is activity on the statement, the adapter sets a CANCEL flag on the statement handle, which the original thread periodically checks to determine if the operation should be canceled, to be done in an appropriate manner.
The ODBC 2.0 Programmer's Reference suggests two techniques for writing thread-safe, multithreaded ODBC applications:
- Have multiple statement handles on a single connection handle, with a single thread for each statement handle.
- Have multiple connection handles, with a single statement handle and single thread for each connection handle.
The application must monitor which operations are being performed on an object. For example, if a thread calls the SQLFetch function on a statement handle and begins to process the data, and a second thread calls the SQLFetch function on the same statement handle into the same buffer, the first thread might get columns from the first row of the rowset mixed with columns from the second row.
Also, the application must prioritize when calling the SQLFreeStmt function. For example, if an application attempts to perform an operation on a statement handle that is being freed, the application blocks on the statement handle. When the application unblocks, it fails with an access violation because the statement handle no longer exists. The application must ensure that the statement handle is inactive before calling an SQLFreeStmt function with an SQL_DROP option, or SQLDisconnect.