Skip to content

TBoldDbValidator never frees its worker threads #93

Description

@bero

TBoldDbValidator never frees the worker threads it creates. TBoldDbValidatorThread.Create (Source/PMapper/Validator/BoldDbValidator.pas) starts the thread without setting FreeOnTerminate; TBoldDbValidatorThread.Execute ends with ThreadList.Remove(self); and nothing else references the thread afterwards - TBoldDbValidator.Destroy does FreeAndNil(fThreadList), which frees the list, not its items. One TThread object (plus its handle) leaks per validator thread per run, on both adapters.

Found while writing the end-to-end validator test for #92 (the same threads also leaked their extra database connection until #92).

Root cause

The validator uses fire-and-forget worker threads but keeps the "owner frees" lifetime model without an owner: the thread removes itself from the only list that knows about it and then simply ends. TBoldDbCopy, the other multi-threaded tool in the same layer, uses TThread.CreateAnonymousThread, which is FreeOnTerminate by construction, and does not have the problem.

Fix

  • TBoldDbValidatorThread.Create: FreeOnTerminate := True. The thread already removes itself from ThreadList at the end of Execute and the completion callback fires from inside the last thread before it frees itself, so no other code holds a reference that could dangle.

Files changed

  • Source/PMapper/Validator/BoldDbValidator.pas
  • UnitTest/Code/Persistence/Test.BoldDbValidator.pas (end-to-end test with a concrete validator thread)

Testing

  • RED: TestValidatorThreadsCompleteAndFreeThemselves (final name) - a test validator whose threads run a trivial query on their extra connection, ThreadCount = 2, driven through Execute against the data module's second persistence handle; asserts the thread list is empty and a live-instance counter on the test thread class returns to 0 — allocation counts turned out unusable for this: FireDAC retains 1–2 blocks per thread that opens a connection until its manager finalizes. Failed with Expected [0] but got [2] (TEndToEndValidatorThread x 2 in the FastMM report) with the fix disabled
  • GREEN after the fix (3 consecutive runs)
  • Full suite green: 2173 found / 2171 passed / 2 ignored / 0 failed / 0 leaked

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions