280 歌单链路三修:开A→开B 竞态防串(5194 串数据) + 92/200 批边界 Load Failed + 歌单列表盘缓存 + 孤儿 .part 回收

ncm_app(REPORT §26, ncm 158ec367 未部署留主会话):
- 打开时快照 plid+代次:appstate_playlist_begin/open_gen/open_idx/reset +
  appstate_load_playlist_songs_ctx(快照 pl 不读 g_st.playlists[],detail 结果落
  staging 锁内原子发布,代次/目标不匹配判 NCM_ERR_STALE 不写全局);playlist_tick
  过期丢弃 + appstate_playlist_reset 清窗口防串。修 5194「我喜欢的音乐」3 首/串数据。
- appstate_song_ensure_range fill-and-continue:bn<m 部分返回/单批网络失败非致命
  (记 NCM_ERR_NOTFOUND/r2),已物化保留+占位行;worker 首屏 track_ids_count>0
  降级非致命(snack)。修 92/200 首歌单点开整页 Load Failed。
- 歌单列表盘缓存 <data_dir>/playlists.bin(magic+ver+ts+数组):home_reload 先缓存
  秒渲 + 后台静默刷新,刷新失败有数据不置错态。修返回首页卡 LOADING(275 遗留)。
- 孤儿 .part/.tmp:evict/total_bytes LRU 扫描顺续删 mtime>7 天(in-flight mtime 新鲜安全)。
验证:新 bench/playlist_race_sim(竞态防串/批边界/非致命/盘缓存/reset)+cache_evict_sim
case9(7 天回收)+window/pagination/search/stream_sim 零回归+test_ncm_core host+mipsel
PASS;build_ncm.sh -Wall -Wextra 0 warning(text 978354/bss 1496484);0 真实请求。
遗留:appstate_logout 未联动删 playlists.bin;g_st.playlists[] 快照拷贝仍有极小交错窗。
This commit is contained in:
MeowOS committed 2026-09-01 21:06:57 +08:00
1 parent d8eeef5c57
commit f0b73e119d
11 files changed
+744 -48

No files matched your search

+12 -5
View File
@@ -168,7 +168,7 @@ static void home_draw_empty(void *ctx)
{
(void)ctx;
if (meow_ui_activity_active() != ACT_HOME) return;
if (g_load_err == 0 && g_st.playlist_count != 0) return;
if (g_st.playlist_count != 0) return; /* 有数据(缓存/已载)即显示列表,后台刷新失败不置空 */
if (g_home_loading) { ncm_draw_empty(r_list, "LOADING", "正在加载歌单..."); return; }
if (g_st.logged_in == 0) ncm_draw_empty(r_list, "NOT SIGNED IN", "请先登录");
else if (g_load_err == NCM_ERR_AUTH) ncm_draw_empty(r_list, "SESSION EXPIRED", "请重新登录");
@@ -201,7 +201,9 @@ static void home_apply(void)
meow_ui_paint_full();
}
/* 后台 worker:唯一走网络的地方(ensure_uid + user_playlist)。 */
/* 后台 worker:唯一走网络的地方(ensure_uid + user_playlist)。
* §26 stale-while-revalidate:网络成功 → appstate_load_playlists 覆写盘缓存 + 更新内存;
* 失败但有缓存在展示 → 保持缓存列表(g_load_err=0),后台静默不打断(断网可离线浏览)。 */
static void *home_worker(void *arg)
{
(void)arg;
@@ -211,7 +213,7 @@ static void *home_worker(void *arg)
if (rc == NCM_OK)
account_vip_maybe_refresh(0); /* §20:超 1 天/到期后各补查一次(worker 线程,不卡 UI) */
pthread_mutex_lock(&g_home_mu);
g_load_err = rc;
g_load_err = (g_st.playlist_count > 0) ? 0 : rc; /* 有数据(缓存/已载)即不置错误态 */
g_home_loading = 0;
g_home_gen++;
pthread_mutex_unlock(&g_home_mu);
@@ -222,9 +224,14 @@ void home_reload(void)
{
if (g_host_mock) { g_load_err = 0; home_apply(); return; }
if (g_home_thr_on) return;
/* §26:进首页先用磁盘缓存秒渲染(若有),后台 worker 静默刷新;无缓存才显示 LOADING。 */
int64_t ts = 0;
int had_cache = (appstate_playlists_cache_load(&ts) == NCM_OK && g_st.playlist_count > 0);
g_load_err = 0;
g_st.playlist_count = 0;
g_home_loading = 1;
if (!had_cache) {
g_st.playlist_count = 0; /* 无缓存 → LOADING 空态 */
g_home_loading = 1;
}
g_home_thr_on = 1;
if (pthread_create(&g_home_thr, NULL, home_worker, NULL) != 0) {
g_home_thr_on = 0; g_home_loading = 0; g_load_err = NCM_ERR_IO;