Skip to content

ThreadPool/ThreadChannel: no test coverage for transferring $this-bound closures (incl. method-as-closure) #154

@EdmondDantes

Description

@EdmondDantes

Clients reported a bug when transferring a closure bound to $this. We have an extensive $this test matrix (19 tests, tests/thread/053–071) — but it only covers spawn_thread. ThreadPool::submit and ThreadChannel::send are separate transfer paths and currently have zero $this coverage.

Coverage gap

  • tests/thread_pool/ — closure tests cover only use() vars (024), class type-hints (029/031-union), complex op_array features (031). None bind $this.
  • tests/thread_channel/037 — closure transfer, but not $this-bound.

Current behavior (empirical)

The ThreadPool path works today for a basic $this closure — deep-copy of $this, parent unchanged, requires a bootloader to declare the class on the worker (same as spawn_thread):

worker: n=42 tag=hi class=Worker
result=999
parent n=42

But because nothing is tested, we cannot rule out divergence on specific sub-cases.

Tasks

  1. Port the full $this matrix to ThreadPool::submit, mirroring tests/thread/053–071:
    • base property access + mutation isolation
    • private / protected properties (the original client repro, 055)
    • $this self-cycle ($this->self === $this)
    • readonly property
    • enum instance as $this + enum-typed property
    • WeakReference property (target reachable / unreachable)
    • typed/strict properties
    • missing class without bootloader → clear error, no SEGV
  2. Method-as-closure cases (class refers to its own method as a closure):
    • first-class callable from instance method: $this->method(...) / $obj->method(...)
    • Closure::fromCallable([$this, 'method'])
    • Closure::bind to an object before submit
    • arrow fn fn() => $this->x
    • nested closure inheriting $this
    • first-class callable from a static method (no $this)
  3. Add $this-bound + method-as-closure coverage to ThreadChannel::send.
  4. Reproduce the client's exact case to confirm whether any sub-case (non-transferable property, cycle, private props, method-as-closure) diverges from spawn_thread.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtestsTest coverage task

Type

No fields configured for Bug.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions