Summary
Establish ecosystem-wide guidelines for implementing singletons and managing static objects to prevent Static Destruction Order Fiasco (SDOF) across all kcenon system libraries.
Background
The Problem
Multiple ecosystem projects have encountered SDOF issues during process termination:
Current Ad-hoc Solutions
Different projects have applied various solutions independently:
- Intentional Leak pattern - Don't destroy singletons
- atexit handlers - Set shutdown flags before destruction
- Defensive checks - Skip operations if shutting down
Without unified guidelines, each project reinvents solutions, leading to:
- Inconsistent implementations
- Missed edge cases
- Difficulty maintaining cross-project compatibility
Proposed Guidelines
1. Singleton Pattern Selection
| Use Case |
Recommended Pattern |
Example |
| Logger, metrics (accessed from destructors) |
Intentional Leak |
thread_logger |
| Thread pools (long-lived, shared) |
Intentional Leak |
io_context_thread_manager |
| Configuration (read-only after init) |
Meyer's Singleton |
- |
| Factory (not accessed from destructors) |
Meyer's Singleton |
- |
2. Intentional Leak Pattern Template
class MySingleton {
public:
static MySingleton& instance() {
// Intentionally leak to avoid SDOF.
// Memory is reclaimed by OS on process termination.
// This singleton may be accessed during other singletons' destruction.
static MySingleton* instance = new MySingleton();
return *instance;
}
// Optional: Explicit shutdown for graceful cleanup before exit
static void prepare_shutdown() {
// Set flags, flush buffers, etc.
// Called via atexit or explicitly by application
}
private:
MySingleton() {
// Register shutdown handler early
std::atexit(prepare_shutdown);
}
};
3. shared_ptr with No-op Deleter
For objects managed by shared_ptr that may outlive static destruction:
auto* obj = new MyClass();
auto ptr = std::shared_ptr<MyClass>(
obj,
[](MyClass*) { /* no-op deleter - intentional leak */ }
);
4. Documentation Requirements
Each singleton should document:
- Why the pattern was chosen
- Memory impact (typically ~few KB)
- Shutdown behavior (what happens at process exit)
- Thread safety guarantees
5. Testing Requirements
- Test with Address Sanitizer (ASan)
- Test with Thread Sanitizer (TSan)
- Verify no SDOF on Ubuntu (strictest glibc checks)
Proposed Location
Add guidelines document to common_system:
docs/SINGLETON_GUIDELINES.md - Full documentation
include/kcenon/common/patterns/singleton.h - Optional template implementations
Acceptance Criteria
Benefits
- Consistency: All ecosystem projects follow same patterns
- Maintainability: Single source of truth for SDOF prevention
- Onboarding: Clear guidelines for new contributors
- Debugging: Easier to identify SDOF issues when patterns are documented
Related Issues
References
Summary
Establish ecosystem-wide guidelines for implementing singletons and managing static objects to prevent Static Destruction Order Fiasco (SDOF) across all kcenon system libraries.
Background
The Problem
Multiple ecosystem projects have encountered SDOF issues during process termination:
thread_loggerandthread_poolSDOFio_context_thread_managerandbasic_thread_poolSDOFfree(): invalid pointer, heap corruption, crash on Ubuntu CICurrent Ad-hoc Solutions
Different projects have applied various solutions independently:
Without unified guidelines, each project reinvents solutions, leading to:
Proposed Guidelines
1. Singleton Pattern Selection
thread_loggerio_context_thread_manager2. Intentional Leak Pattern Template
3. shared_ptr with No-op Deleter
For objects managed by shared_ptr that may outlive static destruction:
4. Documentation Requirements
Each singleton should document:
5. Testing Requirements
Proposed Location
Add guidelines document to common_system:
docs/SINGLETON_GUIDELINES.md- Full documentationinclude/kcenon/common/patterns/singleton.h- Optional template implementationsAcceptance Criteria
SINGLETON_GUIDELINES.mdin common_systemBenefits
Related Issues
References