All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
examples/Starter/Starter.lpr— a heavily-commented "Hello, ThreadPool" entry point for new users; includes compile instructions and expected output in the file header- README: decision flowchart for choosing
ThreadPool.SimplevsThreadPool.ProducerConsumer - README: Queue overload reference table documenting all 4
Queuesignatures side-by-side with use-cases and examples - README: Common Mistakes section covering the four most frequent pitfalls (free-before-WaitForAll, missing WaitForAll, LastError overwrites, manual free of GlobalThreadPool)
- README: compilation sanity-check section with
fpcandlazbuildone-liners, expected output, and{$mode objfpc}{$H+}reminder - README:
LastErroroverwrite warning — clarifies only the last exception per pool cycle is stored {$REGION}/{$ENDREGION}grouping inThreadPool.Simple.pas(Public API, Internal Worker Thread, Internal Work Item, Global instance){$REGION}/{$ENDREGION}grouping inThreadPool.ProducerConsumer.pas(Public API, Internal Worker Thread, Internal Work Item, Internal Queue, DebugLog)- Object lifetime
WARNINGcomments inSimpleDemo.lprandProdConSimpleDemo.lprexplaining why objects must not be freed beforeWaitForAll
Test07_ParallelExecution: removedLogTestcalls fromIncrementCounter— 2 000 serialisedWriteLncalls across 1 000 tasks were the bottleneck, consistently exceeding the timing assertion; these calls were present since the test was first writtenTest08_QueueFullBehavior: replacedSlowTask(250 ms) withLongTask(5 000 ms) so the single worker cannot drain the 2-slot queue before the third enqueue — the race condition was present since the test was first writtenTest12_LoadFactorCalculation: increased queued task count from 2 to 50 —LoadFactordrops to 0 the momentTryDequeuesucceeds (not when execution finishes), so 4+ workers racing to dequeue 2 tasks left the queue empty before the assertion ran; the flaw was present since the test was first written
ThreadPool.ProducerConsumer— second thread pool implementation with fixed-size circular queue (default 1 024 items) and built-in backpressure- Configurable
TBackpressureConfigrecord (load thresholds, adaptive delays, max retry attempts) EQueueFullExceptionraised when queue remains full after all retry attemptsTThreadSafeQueuewithLoadFactor,TryEnqueue,TryDequeueWorkQueueproperty onTProducerConsumerThreadPoolfor monitoring and configuration- 3 new Producer-Consumer examples:
ProdConSimpleDemo,ProdConSquareNumbers,ProdConMessageProcessor - API and technical documentation for
ThreadPool.ProducerConsumer - Documentation: Interface Reference Counting and Object Lifetime Management in FPC
- Lazarus package (
package/lazarus/threadpool_fp.lpk)
- Incorrect freeing of work items in
ThreadPool.ProducerConsumer - Double decrement of work item counter
- Race condition in exception propagation from worker threads
ThreadPool.Typesunit — shared interfaces (IThreadPool,IWorkItem,IWorkerThread) and base classTThreadPoolBase- Thread count safety limits: minimum 4 threads, maximum 2×
ProcessorCount ClearLastErrormethod on all pool implementations- Comprehensive unit tests for
ThreadPool.Simple
- Refactored
ThreadPool.Simpleonto the newTThreadPoolBaseclass - Improved method names in unit tests
- Race condition in error handling in
ThreadPool.Simple
- Thread count safety: enforced minimum and maximum bounds
- Technical documentation and sequence diagrams
SimpleWordCounterandSimpleSquareNumbersexamples
- Improved comments in the interface section of the unit
- Initial implementation of
ThreadPool.Simplewith globalGlobalThreadPoolsingleton - 4
Queueoverloads: plain procedure, object method, indexed procedure, indexed method WaitForAllandLastError/ClearLastErrorSimpleDemoandSimpleThreadpoolDemoexamples- MIT licence