mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 02:08:47 +00:00
tunnel: fix keyring panic on Linux (#185066)
tunnel: fix keyring panic on Linxu Fixes #184792 Reported on https://github.com/hwchen/keyring-rs/issues/132
This commit is contained in:
@@ -20,7 +20,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use gethostname::gethostname;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use std::{cell::Cell, fmt::Display, path::PathBuf, sync::Arc};
|
||||
use std::{cell::Cell, fmt::Display, path::PathBuf, sync::Arc, thread};
|
||||
use tokio::time::sleep;
|
||||
use tunnels::{
|
||||
contracts::PROD_FIRST_PARTY_APP_ID,
|
||||
@@ -210,6 +210,48 @@ const KEYCHAIN_ENTRY_LIMIT: usize = 128 * 1024;
|
||||
|
||||
const CONTINUE_MARKER: &str = "<MORE>";
|
||||
|
||||
/// Implementation that wraps the KeyringStorage on Linux to avoid
|
||||
/// https://github.com/hwchen/keyring-rs/issues/132
|
||||
struct ThreadKeyringStorage {
|
||||
s: Option<KeyringStorage>,
|
||||
}
|
||||
|
||||
impl ThreadKeyringStorage {
|
||||
fn thread_op<R, Fn>(&mut self, f: Fn) -> R
|
||||
where
|
||||
Fn: 'static + Send + FnOnce(&mut KeyringStorage) -> R,
|
||||
R: 'static + Send,
|
||||
{
|
||||
let mut s = self.s.take().unwrap();
|
||||
let handler = thread::spawn(move || (f(&mut s), s));
|
||||
let (r, s) = handler.join().unwrap();
|
||||
self.s = Some(s);
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ThreadKeyringStorage {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
s: Some(KeyringStorage::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StorageImplementation for ThreadKeyringStorage {
|
||||
fn read(&mut self) -> Result<Option<StoredCredential>, WrappedError> {
|
||||
self.thread_op(|s| s.read())
|
||||
}
|
||||
|
||||
fn store(&mut self, value: StoredCredential) -> Result<(), WrappedError> {
|
||||
self.thread_op(move |s| s.store(value))
|
||||
}
|
||||
|
||||
fn clear(&mut self) -> Result<(), WrappedError> {
|
||||
self.thread_op(|s| s.clear())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct KeyringStorage {
|
||||
// keywring storage can be split into multiple entries due to entry length limits
|
||||
@@ -325,7 +367,10 @@ impl Auth {
|
||||
return op(s);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let mut keyring_storage = KeyringStorage::default();
|
||||
#[cfg(target_os = "linux")]
|
||||
let mut keyring_storage = ThreadKeyringStorage::default();
|
||||
let mut file_storage = FileStorage(PersistedState::new(self.file_storage_path.clone()));
|
||||
|
||||
let keyring_storage_result = match std::env::var("VSCODE_CLI_USE_FILE_KEYCHAIN") {
|
||||
|
||||
Reference in New Issue
Block a user