{"record":{"id":"3e1d67386fb1d7b4","repo":"rust-lang/rust-analyzer","slug":"tried-to-get-qos-of-thread-which-has-opted-out-of","errorCode":null,"errorMessage":"tried to get QoS of thread which has opted out of QoS","messagePattern":"tried to get QoS of thread which has opted out of QoS","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/stdx/src/thread/intent.rs","lineNumber":254,"sourceCode":"            let errno = unsafe { *libc::__error() };\n            unreachable!(\"`pthread_get_qos_class_np` failed unexpectedly (os error {errno})\");\n        }\n\n        match qos_class_raw {\n            libc::qos_class_t::QOS_CLASS_USER_INTERACTIVE => Some(QoSClass::UserInteractive),\n            libc::qos_class_t::QOS_CLASS_USER_INITIATED => Some(QoSClass::UserInitiated),\n            libc::qos_class_t::QOS_CLASS_DEFAULT => None, // QoS has never been set\n            libc::qos_class_t::QOS_CLASS_UTILITY => Some(QoSClass::Utility),\n            libc::qos_class_t::QOS_CLASS_BACKGROUND => Some(QoSClass::Background),\n\n            libc::qos_class_t::QOS_CLASS_UNSPECIFIED => {\n                // Using manual scheduling APIs causes threads to “opt out” of QoS.\n                // At this point they become incompatible with QoS,\n                // and as such have the “unspecified” QoS class.\n                //\n                // Panic instead of returning an error\n                // to maintain the invariant that we only use QoS APIs.\n                panic!(\"tried to get QoS of thread which has opted out of QoS\")\n            }\n        }\n    }\n\n    pub(super) fn thread_intent_to_qos_class(intent: ThreadIntent) -> QoSClass {\n        match intent {\n            ThreadIntent::Worker => QoSClass::Utility,\n            ThreadIntent::LatencySensitive => QoSClass::UserInitiated,\n        }\n    }\n}\n\n// FIXME: Windows has QoS APIs, we should use them!\n#[cfg(not(target_vendor = \"apple\"))]\nmod imp {\n    use super::ThreadIntent;\n\n    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/stdx/src/thread/intent.rs#L236-L272","documentation":"The macOS counterpart of reading thread priority: `get_current_thread_qos_class` panics when the thread reports the 'unspecified' QoS class, which happens once a thread has opted out of QoS via manual scheduling APIs (e.g. `pthread_setschedparam`) or manual scheduling modes. As with the setter, the code panics rather than returning an error to preserve the invariant that only QoS APIs manage thread intent.","triggerScenarios":"Calling `get_current_thread_qos_class` on a thread that previously used manual scheduling APIs, causing it to report QOS_CLASS_UNSPECIFIED; measuring/adjusting intent on a thread whose policy was changed by embedding code.","commonSituations":"Same family as the setter panic: mixing rust-analyzer's ThreadIntent abstraction with platform-specific thread priority controls on macOS; libraries that tweak thread policy when they attach to host threads.","solutions":["Remove manual scheduling calls from threads whose intent is managed via ThreadIntent/QoS","Run the intent/QoS logic on a freshly spawned, unmodified thread","Treat QoS as the single source of truth for thread priority in the process"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Detect QoS opt-out before reading intent:\nlet class = libc::qos_class_self();\nif class == libc::QOS_CLASS_UNSPECIFIED {\n    // thread opted out; do not call get_current_thread_qos_class\n}","typeGuard":null,"tryCatchPattern":"let qos = std::panic::catch_unwind(||\n    stdx::thread::get_current_thread_qos_class()\n).unwrap_or(None); // treat as unknown priority","preventionTips":["Avoid mixing manual scheduling APIs with QoS reads on the same thread","Check QOS_CLASS_UNSPECIFIED via raw APIs before invoking the helper","Document thread-policy constraints for embedders of rust-analyzer"],"tags":["rust","macos","thread-priority","qos","panic"],"backgroundTag":"thread-qos-optout","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}