From fbc64caec5a252b78cb7207161ee34e241f53a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E7=BF=94=E5=AE=87?= Date: Tue, 21 Apr 2026 08:05:01 +0800 Subject: [PATCH] =?UTF-8?q?v2.2.2:=20fix=20UI=20hang=20on=20plugin=20insta?= =?UTF-8?q?ll=20=E2=80=94=20bootstrap=20off=20main=20queue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptom: installing v2.2.1 caused Mio Island to freeze ("卡崩") on launch. Not a true crash, just the main runloop stuck long enough to trip the "app not responding" state. Root cause: MediaRemoteAdapterSource.spawn() scheduled bootstrapGet() on `DispatchQueue.main.asyncAfter(+0.3)`. bootstrapGet runs a Perl subprocess that dlopens MediaRemoteAdapter.framework then calls `get` — that cold path takes 500ms to 1s in the worst case. During that entire window, `proc.waitUntilExit()` blocks the main thread. No UI events drain, SwiftUI drops frames, window looks hung. Fix: - Move the `DispatchQueue.main.asyncAfter` to `DispatchQueue.global(qos: .userInitiated).asyncAfter` so the Perl cold path runs on a background queue. - Since `currentInfo` is now mutated from both queues (bg in bootstrap, main in parseLine/stream), hop the merge + onUpdate back onto main after we parse the JSON on bg. Single writer, no data race. - parseLine is unchanged — still runs on main via the FileHandle readabilityHandler hop. Verified 30s alive, debug log shows bootstrap + stream rx both emitting correctly. Co-Authored-By: Claude Opus 4.7 (1M context) --- Info.plist | 4 +-- .../sources/MediaRemoteAdapterSource.swift | 30 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Info.plist b/Info.plist index 9946c90..427a8b5 100644 --- a/Info.plist +++ b/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.2.1 + 2.2.2 CFBundleVersion - 10 + 11 NSPrincipalClass MusicPlugin.MusicPlugin