Skip to content

Refactor runtime ownership and worker lifecycle #609

Description

@somethingwithproof

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

  • Make child registry ownership exclusive and cancellation-safe.
  • Make signal notification async-signal-safe.
  • Introduce joinable worker lifecycle and ordered teardown.
  • Introduce immutable poll jobs and stable host results.
  • Separate Net-SNMP runtime ownership from per-worker sessions.
  • Introduce checked database leases.
  • Isolate logging state and serialize complete writes.
  • Split poller.c along execution, aggregation, persistence, and policy
    boundaries.
  • Encapsulate ping probe resources and privilege transitions.
  • Remove obsolete global locks and mutable globals.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions