Refactor a Buggy C++ Object Pool Into a Correct, Thread-Safe Template
Context
You are given a buggy C++ object pool that suffers from races, double-free risks, ABA problems, and resource leaks during concurrent borrow/return operations. Refactor it into a robust template that is correct under concurrency and safe to shut down.
Assume C++17 or later.
Requirements
-
Implement a generic, thread-safe object pool template for objects of type T.
-
Provide borrow() that blocks when the pool is empty and creates up to a maximum capacity.
-
Also provide an overload with a timeout (e.g., borrow_for(duration)).
-
Ensure fairness among waiters (FIFO) and avoid spurious wakeups.
-
Provide returnObject(obj) to safely return an object:
-
Reject invalid returns (wrong pool) and duplicate returns.
-
Optionally reset objects before reuse (configurable functor).
-
Enforce RAII via a scoped handle that returns the object automatically when destroyed.
-
Handle must be movable but not copyable.
-
Ensure safe shutdown:
-
Destructor stops producers/consumers, wakes waiters, and releases resources without deadlocks.
-
Avoid busy-waiting; use std::mutex, std::condition_variable, and std::atomic correctly.
-
Prevent ABA issues (e.g., generation counters per item).
-
Include minimal unit tests demonstrating correctness under multiple threads.
-
Document the time complexity of core operations.
Deliverables: A single self-contained C++17 implementation plus minimal unit tests and brief complexity notes.