Elevate Software


Login Login

ProductsBulletSalesBulletSupportBulletDownloadsBulletAbout





Home » Elevate Software Blog » ElevateDB External Modules in Multi-Threaded Delphi Applications

Icon ElevateDB External Modules in Multi-Threaded Delphi Applications

Posted by Tim Young on Tue, Feb 23 2010
An issue recently surfaced with a customer regarding the use of an ElevateDB external module in a Delphi application that was using multiple threads to execute some SQL scripts. The external module was called within the scripts to do some text processing, and there were only two threads being launched to execute the scripts in the background. Much to the customer's dismay, the external module kept blowing up in various places, with no real pattern or indication of the cause.

For those that aren't aware of what an ElevateDB external module is, this section of the manual will serve as a good primer:

External Modules

The customer was kind enough to send me a cut-down version of the application, and after playing around with the application and the external module in the debugger for a few hours, the lightbulb finally came on. We had experienced the same issue with our DBISAM ODBC Driver a few years ago, and the cause was very simple: DLLs that are used in multi-threaded Delphi applications that use TThread objects, but don't themselves use TThread objects, will not have the global IsMultiThread variable (System unit) set properly. The IsMultiThread variable is only set to True by Delphi automatically when the TThread class is instantiated, or when the BeginThread procedure (System unit) is called manually. The BeginThread procedure is what sets the IsMultiThread variable, but TThread calls the BeginThread procedure when a TThread instance is created.

So, why is this bad ? Without the IsMultiThread variable set to True, the Delphi memory manager does not know that it needs to use mutual exclusion techniques such as critical sections or interlocked calls to ensure that the multiple threads don't step on each other when allocating or deallocating memory.

So, the solution was to simply add this code in the initialization section of the external module's main unit:

initialization
   IsMultiThread := True;
end

Having said all that, this variable should be set already in the template projects that we provide for Delphi in the Object Repository, so we will be including this as a fix in the next build (2.03 Build 9). The flag does result in a little extra overhead in the memory manager, but saves a lot of grief trying to track down random AVs and memory overwrites.

Tags: ElevateDB, External Modules, DLLs, ThreadsPermanent Link

Comments Comments (0) You must be logged in to comment

Image