Skip to content

STL WaitTimer teardown race reintroduced after #998 #1003

Description

@jhugard

Summary

PR #998 restored the pre-#975 STL wait-timer backend to resolve the delayed-callback strand tracked by #973. That restoration reintroduced the delayed-callback teardown lifetime issue previously tracked as #974 and addressed by PR #975.

On STL timer platforms, a queue can begin teardown after a delayed callback has become eligible for dispatch. The timer backend can then continue dispatching against state whose owning queue has already entered destruction. This is a lifetime correctness violation during normal XTaskQueue termination.

Affected API surface

STDAPI XTaskQueueSubmitDelayedCallback(
    _In_ XTaskQueueHandle queue,
    _In_ XTaskQueuePort port,
    _In_ uint32_t delayMs,
    _In_opt_ void* callbackContext,
    _In_ XTaskQueueCallback* callback);

STDAPI XTaskQueueTerminate(
    _In_ XTaskQueueHandle queue,
    _In_ bool wait,
    _In_opt_ void* callbackContext,
    _In_opt_ XTaskQueueCallback* callback);

No public API signature change is needed.

Expected behavior

After queue-owned timer teardown begins, delayed callback dispatch must satisfy one of these guarantees:

  • A callback that has not begun dispatching must not begin.
  • A callback that has already begun dispatching must complete before the timer and its callback state are destroyed.

Queue termination may deliver pending callbacks as canceled according to the existing XTaskQueue contract, but it must not permit callback dispatch through state that has already been retired.

Actual behavior

Under the STL timer backend restored by PR #998, queue termination can overlap an eligible delayed callback, so timer-owned dispatch outlives the queue-owned timer state.

The externally observable result can be a crash, memory corruption, or other undefined behavior during queue teardown. The problem is timing-sensitive, so it may instead appear as intermittent shutdown instability.

Reproduction

The race lives in the narrow window after the STL timer worker has selected a due callback for dispatch but before it invokes it. Reproducing it deterministically requires stopping the worker in that window and then terminating the owning queue. That window is internal to the STL backend and is not reachable through the public XTaskQueue API alone, so a reliable reproduction must drive the backend directly; otherwise the failure is timing-sensitive and appears only intermittently during queue teardown.

Scope and impact

The issue affects platforms that use the STL wait-timer backend, including Linux and other non-Windows configurations that compile that backend.

The risk is greatest for applications that frequently create and terminate queues while delayed callbacks are pending or becoming due. It is particularly concerning when queue lifetime is coupled to callback-driven shutdown or other synchronous teardown paths.

Relationship to prior work

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions