Skip to content

[实现] stop() 清空未消费 seek 槽并锁定状态契约 #113

Closed

Description

@wt159

承接 #112 的决议。本票不修复 SIGSEGV:42488656322 attempt 1 的崩溃根因仍未定位(Linux CI / 无 core / 无 ASan),本票只消除被取证确认为 100% 命中的状态契约违反,并为它建立长期判据。

改动清单(严格最小化)

  1. sdk/audio/decode/AudioStreamDecoder.cpp — stop() 在 m_thread.join() 之后、m_state.store(IDLE) 之前补一行 m_seekRequestMs.store(-1);。
    • 依据:cancelRequested()(:451-457)把「槽内有值」当取消;start() 本就在 stop() 之后清槽(:174),seekToMs() 在 IDLE 时直接返回,解码线程此时已 join —— 正常路径行为等价。
  2. sdk/audio/decode/AudioStreamDecoder.h / .cpp — 两个测试专用方法(SDK 内部类型,不进 soundbridge::Player 公开 API,生产路径零调用):
    • void setPendingSeekForTest(int64_t targetMs):m_seekRequestMs.store(targetMs, std::memory_order_release)
    • int64_t pendingSeekMsForTest() const:m_seekRequestMs.load(std::memory_order_acquire)
    • 只在控制线程调用;m_seekRequestMs 已有的解码线程 store 用默认 seq_cst,与 acquire 兼容。
  3. sdk/test/unit/test_stream_decoder.cpp(归属 sdk_unit_tests,与 C1/C5 判据同目标)— 新用例:
    decoder.setPendingSeekForTest(5000);
    decoder.stop();
    CHECK(decoder.pendingSeekMsForTest() == -1);
    
    不启解码线程、不依赖真实素材、不命中任何时序窗口 → 确定性、毫秒级、可红可绿。这是 [决策] 强制重审 seek 竞态:批准第二次限定例外与状态契约加固 #112 批准的第二次限定例子的全部范围。

明确不做

验收

  • 变异验证:去掉 stop() 的清槽一行 → 新用例红;还原 → 绿。证明判据不是摆设。
  • 稳定性闸门:分支与 master 各 ≥10 轮 ctest -j4 同轮数对照,分支假红率不得高于基线;钩子不得落解码线程 / 判据主循环;两轴 code-review。
  • 跨平台:PR 阶段 Linux sdk-coverage + Windows sdk-windows 双绿(只认 gh run view <id> --json status,conclusion,attempt)。
  • 文档回填:doc/player-state-contract.md §10.4 或 AGENTS.md NOTES 记录破例、取证数据、H2/H3/H4 未改或未验的如实状态;745ba7b 门槛条不删,只补「11-09 用户强制重审」破例留痕。

反悔通道

若日后证明该判据只锁实现细节、无契约价值,须另开新票同时撤掉两个钩子与该用例,不得只删判据留下无门禁的改动。

Activity

  1. wt159 commented on Nov 9, 2026

    @wt159
    OwnerAuthor

    Resolution:实现完成但稳定性闸门未过,全部撤回、未进 master

    ⚠️ 本票正文是历史留痕、不修改。正文列出的三文件改动已在分支实现并完成除稳定性闸门外的全部验证,但按 #112 决议 4 写死的闸门撤回,master 中不存在 stop() 清槽、setPendingSeekForTest / pendingSeekMsForTest 钩子或 AudioStreamDecoder Stop Contract 用例。完整依据见 PR #114 结论 comment 与 #112 resolution。

    实际做到的(取证有效,但不足以放行)

    验收项 结果
    改动清单严格最小化 3 文件 +47 行,与正文一致;未改 :546 / MusicPlayer.cpp / 公开 API / 七个 void 入口 / 任何既有判据 / TIMEOUT / 坏输入 55 例 / 14 目标 / CI 配置
    钩子闸门 release/acquire、只在控制线程、不落解码线程或判据主循环;注释按两轴 review 意见修正
    变异验证 去掉 stop() 的 m_seekRequestMs.store(-1) → 新用例精确红;字节一致还原 → 绿(1 case / 2 assertions / 515 skipped)
    两轴 code-review 两条意见(内存序注释不精确、断言超出票范围)已修并重跑,删掉 state() / canDecode() 两条无关 CHECK
    临时探针清理 [DEBUG-seekstop] 探针与诊断用例已 git checkout HEAD -- 还原,零残留
    跨平台 CI PR #114 阶段 Linux 42544814467、Windows 42544814456 均 completed/success attempt=1
    稳定性闸门 未通过:分支两组 ctest -j4 各 9/10(两次同形态 afterMonotonic),真实 master 同轮数 10/10 全绿、0 SIGSEGV

    撤回动作

    按 #112 决议 4 与 PR #114 事先写死的规则「分支假红率高于基线即撤回全部 sdk/ 改动」:PR #114 已 CLOSED、不合并;AudioStreamDecoder.cpp / .h / test_stream_decoder.cpp 三文件不进 master;不放宽判据 / TIMEOUT / 基线 / CI 配置,也不以「失败用例与改动零交集」为由事后放宽闸门。分支 implement/seek-stop-state-hygiene (ca3543fef) 仅作取证留痕。

    统计诚实:20 轮对 10 轮、失败用例与本改动零交集,不能证明因果;这是「按事先约定规则撤回」,不是「已证实改动放大假红」。

    反悔通道的落实

    正文「反悔通道」要求撤钩子与判据必须同时、不得只删判据留下无门禁的改动。本次是整体撤回:钩子、生产一行、判据三者都不在 master,天然满足该条款,无「无门禁的改动」遗留。doc/player-state-contract.md §10.4 与 AGENTS.md NOTES 已记录破例、取证数据、撤回结论,以及 H2 未改 / H3·H4 未验 / 根因未定位的如实状态;745ba7b 门槛条不删,只补 11-09 破例留痕。

    后续

    本票不重开。要重新落地须另开新票:先解决基线假红放大或取得 Linux 侧复现 / ASan 证据,再重走全套闸门;不得直接合并或 cherry-pick ca3543fef。SIGSEGV 根因仍未定位,本 effort 从未声称修复它。

  2. wt159 commented on Nov 9, 2026

    @wt159
    OwnerAuthor

    实现完成但稳定性闸门未过,全部撤回、未进 master;完整 resolution 见上方 comment。

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agent信息完备,agent 可直接开工

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions