Problem
Spine's runtime ownership is spread across global arrays, detached workers,
semaphores, and numbered locks. Several resources can outlive the state that
tracks them, and some locks protect access without defining who owns the
underlying object. This makes shutdown, cancellation, and error recovery hard
to reason about and test.
This issue tracks the architecture work. Existing defect reports remain the
source of truth for their specific bugs.
Proposed direction
- Use joinable workers. Treat
pthread_join() as proof that teardown is safe;
keep semaphores only for admission control.
- Replace the cross-thread
LOCK_HOST_TIME handoff with a valid synchronization
primitive and immutable work items.
- Give each host one stable result object shared by its jobs and owned by the
parent until every worker has joined.
- Transfer
nft_popen registry entries atomically to the one thread responsible
for closing and reaping each child.
- Initialize Net-SNMP once, then give each worker exclusive ownership of its
sessions.
- Express database connections as checked leases with one release path.
- Move mutexes into the objects whose invariants they protect, then retire the
numbered global lock registry where it is no longer needed.
- Keep signal handlers async-signal-safe. Perform coordinated shutdown in the
main thread.
- Split polling execution, result aggregation, persistence, and policy without
changing collected values or database effects.
php.c process ownership is being handled separately and should be integrated
through the same runtime contract without duplicating that work.
Existing related issues
Implementation order
Acceptance criteria
- Every allocation, descriptor, child PID, session, connection, and worker has
one documented owner at each point in its lifetime.
- Shutdown stops new work, drains or cancels active work, joins all workers,
then destroys shared services.
- No thread unlocks a mutex acquired by another thread.
- Cancellation and every error path release or transfer all owned resources.
- Existing polling output, exit status, and database behavior remain compatible
unless a linked defect explicitly changes them.
- New and rewritten ownership code has 100% line and branch coverage.
- Tests link the production objects rather than copies of their logic.
- Docker integration covers real child processes, MariaDB, and Net-SNMP v1,
v2c, and v3.
- ThreadSanitizer, ASan/UBSan, Valgrind, fault-injection, cancellation, and
high-concurrency stress tests pass for the changed paths.
Pull request coordination
PR #597 already changes several of these files. Work that touches the same
subsystem should be folded into that branch after its active PHP work finishes,
or rebased onto develop after #597 merges. Do not keep competing pull requests
open against the same ownership code.
Problem
Spine's runtime ownership is spread across global arrays, detached workers,
semaphores, and numbered locks. Several resources can outlive the state that
tracks them, and some locks protect access without defining who owns the
underlying object. This makes shutdown, cancellation, and error recovery hard
to reason about and test.
This issue tracks the architecture work. Existing defect reports remain the
source of truth for their specific bugs.
Proposed direction
pthread_join()as proof that teardown is safe;keep semaphores only for admission control.
LOCK_HOST_TIMEhandoff with a valid synchronizationprimitive and immutable work items.
parent until every worker has joined.
nft_popenregistry entries atomically to the one thread responsiblefor closing and reaping each child.
sessions.
numbered global lock registry where it is no longer needed.
main thread.
changing collected values or database effects.
php.cprocess ownership is being handled separately and should be integratedthrough the same runtime contract without duplicating that work.
Existing related issues
SIGPIPEhandlingpoll_host()constructionImplementation order
poller.calong execution, aggregation, persistence, and policyboundaries.
Acceptance criteria
one documented owner at each point in its lifetime.
then destroys shared services.
unless a linked defect explicitly changes them.
v2c, and v3.
high-concurrency stress tests pass for the changed paths.
Pull request coordination
PR #597 already changes several of these files. Work that touches the same
subsystem should be folded into that branch after its active PHP work finishes,
or rebased onto
developafter #597 merges. Do not keep competing pull requestsopen against the same ownership code.