From aa46a936f29f219fdff8a87f2d2a3307e1208726 Mon Sep 17 00:00:00 2001 From: "Chris West (Faux)" Date: Thu, 13 Jul 2017 13:38:48 +0100 Subject: [PATCH] give in and lazy_singleton the cache --- Cargo.toml | 1 + apt-c/lib.cpp | 2 +- src/lib.rs | 13 ++++++------- src/raw.rs | 34 ++++++++++++++++++++-------------- src/sane.rs | 21 +++++---------------- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff6ee38..70f56e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" authors = ["Chris West (Faux) "] [dependencies] +lazy_static = "0.2.8" libc = "0.2.26" diff --git a/apt-c/lib.cpp b/apt-c/lib.cpp index 841874a..5d3e4a3 100644 --- a/apt-c/lib.cpp +++ b/apt-c/lib.cpp @@ -26,7 +26,6 @@ extern "C" { void init_config_system(); PCache *pkg_cache_create(); - void pkg_cache_release(PCache *cache); PPkgIterator *pkg_cache_pkg_iter(PCache *cache); PPkgIterator *pkg_cache_find_name(PCache *cache, const char *name); @@ -88,6 +87,7 @@ PPkgIterator *pkg_cache_find_name_arch(PCache *cache, const char *name, const ch return wrapper; } +// TODO: we don't expose this so we always leak the wrapper. void pkg_iter_release(PPkgIterator *wrapper) { delete wrapper; } diff --git a/src/lib.rs b/src/lib.rs index bdfa34d..3df863f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#[macro_use] extern crate lazy_static; extern crate libc; mod raw; @@ -10,17 +11,15 @@ pub use sane::Cache; mod tests { use super::*; -// #[test] - fn list_all() { - let mut cache = Cache::new(); - for name in cache.iter().map(|item| item.pretty_print()) { - println!("{}", name); - } + #[test] + fn pretty_print_all() { + let mut cache = Cache::get_singleton(); + assert!(cache.iter().map(|item| item.pretty_print()).count() > 0); } #[test] fn find_a_package() { - let mut cache = Cache::new(); + let mut cache = Cache::get_singleton(); { let iter = cache.find_by_name("apt"); assert!(!iter.is_empty()); diff --git a/src/raw.rs b/src/raw.rs index cd382a0..af62516 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -15,10 +15,7 @@ pub type PPkgIterator = *mut c_void; extern { /// Must be called exactly once, before anything else? fn init_config_system(); - - /// I'm not convinced you can even call this multiple times. - pub fn pkg_cache_create() -> PCache; - pub fn pkg_cache_release(cache: PCache); + fn pkg_cache_create() -> PCache; pub fn pkg_cache_pkg_iter(cache: PCache) -> PPkgIterator; pub fn pkg_cache_find_name(cache: PCache, name: *const c_char) -> PPkgIterator; @@ -34,14 +31,23 @@ extern { pub fn pkg_iter_pretty(cache: PCache, iterator: PPkgIterator) -> *mut c_char; } -static mut INIT_CONFIG_CALLED: bool = false; - -pub unsafe fn init_config_system_once() { - if INIT_CONFIG_CALLED { - return; - } - - INIT_CONFIG_CALLED = true; - - init_config_system() +pub fn pkg_cache_get() -> PCache { + CACHE.ptr +} + +struct CacheHolder { + ptr: PCache +} + +unsafe impl Sync for CacheHolder {} + +lazy_static! { + static ref CACHE: CacheHolder = { + unsafe { + init_config_system(); + CacheHolder { + ptr: pkg_cache_create() + } + } + }; } diff --git a/src/sane.rs b/src/sane.rs index 5db1102..423ff7e 100644 --- a/src/sane.rs +++ b/src/sane.rs @@ -3,28 +3,17 @@ use std::ffi; use libc; use raw; -// Probably not cloneable / copyable. -/// You might only be able to create one of these per process. +/// A reference to the package cache singleton. +/// Basically just a collection of related methods. #[derive(Debug)] pub struct Cache { ptr: raw::PCache } -impl Drop for Cache { - fn drop(&mut self) { - unsafe { - raw::pkg_cache_release(self.ptr) - } - } -} - impl Cache { - pub fn new() -> Cache { - unsafe { - raw::init_config_system_once(); - Cache { - ptr: raw::pkg_cache_create() - } + pub fn get_singleton() -> Cache { + Cache { + ptr: raw::pkg_cache_get() } }