Skip to content

Fixes logging lifecycle, close semantics, and teardown safety - #7

Merged
cppcooper merged 14 commits into
developfrom
refactors-logging
Sep 26, 2026
Merged

cppcooper merged 14 commits into
developfrom
refactors-logging

Conversation

@cppcooper

Copy link
Copy Markdown
Owner

This PR completes the logging lifecycle refactor and replaces the previous queue-based close behavior with explicit state-driven resource management.

It introduces Closed, Opening, Open, and Closing lifecycle states; makes logger and sink ownership safely publishable across threads; routes ordinary writes through a null fallback while closing or closed; and makes file-sink destruction the authoritative close-completion signal.

close() now supports optional timeouts, handles concurrent callers deterministically, and guarantees that a successful return means the file is actually closed. Reopening is transactional, restores logger, file, and console levels, preserves default-logger ownership when appropriate, and rejects invalid lifecycle transitions.

The Logger<> wrapper now forwards close timeouts while preserving existing zero-argument calls. Log destruction performs bounded cleanup so logger resources are not silently orphaned, and log ID generation is now hidden behind a translation-unit-local atomic counter.

The logging tests were rewritten around the new API contracts, including close completion, repeated and concurrent close calls, timeout behavior, reopen semantics, default logger restoration, closed-state writes, compile-time logging during lifecycle transitions, and teardown behavior. Related [[nodiscard]] test warnings were also cleaned up.

cppcooper and others added 14 commits September 23, 2026 20:09
- Replaces the transient SpriteFrame drawable with an internal frame drawing helper
- Draws raw sprite cells and resolved animation cells directly from their owning objects
* Initializes the first timing interval at DeltaTime construction
* Keeps elapsed queries independent from interval reset
* Adds explicit check-in semantics for starting a new interval
* Uses a shared clock sample when measuring and advancing through operator()
* Avoids losing time between separate elapsed and check-in samples
* Snapshots the observed value while holding the write lock
* Invokes callbacks after releasing variable synchronization
* Prevents callback reentrancy from deadlocking on nested writes
* Preserves the value associated with each set operation for observers
* Requires observed values to be copy constructible
* Snapshots listeners before dispatching callbacks
* Releases listener synchronization before invoking arbitrary callback code
* Prevents callback registration from deadlocking during dispatch
* Uses non-mutating event lookup while holding a shared lock
* Moves registered callbacks into listener storage
- Adds explicit logger lifecycle states and state requirements
- Adds synchronized lifecycle state access and validation
- Makes logger and sink ownership atomically accessible
- Adds lifecycle-aware resource acquisition
- Begins transactional logger construction and close synchronization
- Removes redundant sink handling from common logger operations
- Adds explicit logger lifecycle states and state validation rules
- Adds synchronized lifecycle transitions and close waiting support
- Makes logger and sink ownership atomically accessible
- Adds lifecycle-aware resource acquisition
- Preserves log levels for reopening reconstructed resources
- Revises close and reopen around explicit lifecycle state
- Reduces redundant logger and sink access patterns
- Adds sink-lifetime close completion and condition-variable waiting
- Routes writes through a null fallback while closing or closed
- Makes logger and sink ownership atomically publishable
- Preserves log levels and default logger ownership across reopening
- Makes logger construction transactional with registration rollback
- Serializes lifecycle-sensitive resource and default logger operations
- Moves logging lifecycle helpers into an internal implementation namespace
- Propagates close timeouts through Logger<name>
- Preserves existing zero-argument close calls
- Adds explicit standard-library dependencies for wrapper usage
- Reworks logging tests around lifecycle, close, reopen, timeout, and default-logger contracts
- Adds deterministic coverage for concurrent close and transition states
- Verifies close completion before file inspection
- Exercises compile-time logging during closed and closing states
- Cleans nodiscard warnings in logging, manifest, and memory tests
- Closes logger resources during Log destruction with a bounded timeout
- Preserves sink lifetime safety when external spdlog owners remain
- Removes lingering registry ownership during final teardown
- Hides log ID generation behind a translation-unit-local atomic counter
- Adds destruction coverage to the logging tests
@cppcooper
cppcooper merged commit 03bdc3b into develop Sep 26, 2026
@cppcooper
cppcooper deleted the refactors-logging branch October 15, 2026 01:09
@cppcooper
cppcooper restored the refactors-logging branch October 15, 2026 01:09
@cppcooper
cppcooper deleted the refactors-logging branch October 15, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant