Skip to content

Commit 600114f

Browse files
committed
cargo-credential-libsecret: load libsecret only once
Previously, libsecret was loaded and unloaded multiple times, leading to issues where calls could run indefinitely due to glib not properly cleaning up. Now, libsecret is stored in a OnceLock, ensuring it is only loaded once, preventing unnecessary unload/reload cycles.
1 parent 340d123 commit 600114f

File tree

1 file changed

+17
-5
lines changed
  • credential/cargo-credential-libsecret/src

1 file changed

+17
-5
lines changed

credential/cargo-credential-libsecret/src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod linux {
1515
use std::ffi::{CStr, CString};
1616
use std::os::raw::{c_char, c_int};
1717
use std::ptr::{null, null_mut};
18+
use std::sync::OnceLock;
1819

1920
#[allow(non_camel_case_types)]
2021
type gchar = c_char;
@@ -85,6 +86,21 @@ mod linux {
8586

8687
pub struct LibSecretCredential;
8788

89+
fn get_libsecret() -> Result<&'static Library, Error> {
90+
static LIBSECRET: OnceLock<Library> = OnceLock::new();
91+
// unfortunately `get_or_try_init` is not yet stable
92+
match LIBSECRET.get() {
93+
Some(lib) => Ok(lib),
94+
None => {
95+
let _ = LIBSECRET.set(unsafe { Library::new("libsecret-1.so.0") }.context(
96+
"failed to load libsecret: try installing the `libsecret` \
97+
or `libsecret-1-0` package with the system package manager",
98+
)?);
99+
Ok(LIBSECRET.get().unwrap())
100+
}
101+
}
102+
}
103+
88104
fn label(index_url: &str) -> CString {
89105
CString::new(format!("cargo-registry:{}", index_url)).unwrap()
90106
}
@@ -114,15 +130,11 @@ mod linux {
114130
) -> Result<CredentialResponse, Error> {
115131
// Dynamically load libsecret to avoid users needing to install
116132
// additional -dev packages when building this provider.
117-
let lib;
133+
let lib = get_libsecret()?;
118134
let secret_password_lookup_sync: Symbol<'_, SecretPasswordLookupSync>;
119135
let secret_password_store_sync: Symbol<'_, SecretPasswordStoreSync>;
120136
let secret_password_clear_sync: Symbol<'_, SecretPasswordClearSync>;
121137
unsafe {
122-
lib = Library::new("libsecret-1.so.0").context(
123-
"failed to load libsecret: try installing the `libsecret` \
124-
or `libsecret-1-0` package with the system package manager",
125-
)?;
126138
secret_password_lookup_sync = lib
127139
.get(b"secret_password_lookup_sync\0")
128140
.map_err(Box::new)?;

0 commit comments

Comments
 (0)