Skip to content

RootService bind state can stay pending when startup task fails before service broadcast #210

Description

@Mygod

RootService.bindOrTask() can leave RootServiceManager in a stale pending state if the returned startup task fails before the root service process broadcasts back.

Observed with libsu 6.0.0.

The rough sequence is:

  1. Call RootService.bindOrTask(intent, executor, connection).
  2. RootServiceManager.createBindTask(...) queues a pending bind task and sets the remote/daemon en-route flag.
  3. Caller runs the returned Shell.Task.
  4. Shell startup or task execution fails before the root service manager broadcast is received.
    • For example, Shell.getShell() can fail before shell.execTask(task) runs.
    • This is also relevant to RootService.bind(), because it runs the returned task internally.
  5. No ServiceConnection callback is delivered.
  6. The pending task and en-route flag remain in RootServiceManager.
  7. A later bind attempt can see startup as already en route, return no new startup task, and wait indefinitely.

In librootkotlinx we worked around this by using bindOrTask() instead of bind(), running the returned task ourselves, and reflectively cleaning up RootServiceManager.pendingTasks plus the corresponding REMOTE_EN_ROUTE / DAEMON_EN_ROUTE flag if startup fails before the broadcast arrives.

That workaround is intentionally narrow, but this looks like state that libsu should own. RootService.bind() also appears to make the failure harder to observe because its internal task runner catches/logs IOException from execTask() instead of reporting failure through the bind path.

Expected behavior:

If root-service startup fails before the service manager broadcast completes, libsu should clear the pending bind task and en-route flag, and ideally report the failure through a callback or another observable failure path. At minimum, later bind attempts should not be blocked by stale pending state from the failed startup.

Possible fix direction:

Make the startup task failure-aware/cancellable, or have RootService.bind() / the internal task runner notify RootServiceManager when Shell.getShell() or shell.execTask(task) fails before the service is connected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions