Cache actually carries around a mutex

This is way less insane than the old way, I think. And it seems to work.
This commit is contained in:
Chris West (Faux) 2017-11-17 09:28:57 +00:00
parent e1cf0fa26c
commit 9ee8a3ca09
2 changed files with 31 additions and 17 deletions

View File

@ -3,6 +3,9 @@
/// * `*const c_chars` are short-term borrows
/// * `*mut c_chars` are to be freed by `libc::free`.
use std::sync::Mutex;
use std::sync::MutexGuard;
use libc::c_void;
use libc::c_char;
@ -95,23 +98,25 @@ extern "C" {
pub fn pkg_file_iter_index_type(iterator: PPkgFileIterator) -> *const c_char;
}
pub fn pkg_cache_get() -> PCache {
CACHE.ptr
pub fn pkg_cache_get() -> &'static CACHE {
&CACHE
}
struct CacheHolder {
ptr: PCache,
#[derive(Debug)]
pub struct CacheHolder {
pub ptr: PCache,
}
unsafe impl Sync for CacheHolder {}
unsafe impl Send for CacheHolder {}
lazy_static! {
static ref CACHE: CacheHolder = {
#[derive(Debug)]
pub static ref CACHE: Mutex<CacheHolder> = {
unsafe {
init_config_system();
CacheHolder {
Mutex::new(CacheHolder {
ptr: pkg_cache_create()
}
})
}
};
}

View File

@ -1,6 +1,8 @@
use std::cmp;
use std::ffi;
use std::marker::PhantomData;
use std::sync::Mutex;
use std::sync::MutexGuard;
use libc;
use raw;
@ -12,7 +14,7 @@ use citer::RawIterator;
/// from which most functionality can be accessed.
#[derive(Debug)]
pub struct Cache {
ptr: raw::PCache,
ptr: &'static raw::CACHE,
}
impl Cache {
@ -29,7 +31,11 @@ impl Cache {
///
/// See the module documentation for apologies about how this isn't an iterator.
pub fn iter(&mut self) -> CIterator<PkgIterator> {
unsafe { PkgIterator::new(self, raw::pkg_cache_pkg_iter(self.ptr)) }
let lock = self.ptr.lock().unwrap();
unsafe {
let raw_iter = raw::pkg_cache_pkg_iter(lock.ptr);
PkgIterator::new(lock, raw_iter)
}
}
/// Find a package by name. It's not clear whether this picks a random arch,
@ -37,10 +43,11 @@ impl Cache {
///
/// The returned iterator will either be at the end, or at a package with the name.
pub fn find_by_name(&mut self, name: &str) -> CIterator<PkgIterator> {
let lock = self.ptr.lock().unwrap();
unsafe {
let name = ffi::CString::new(name).unwrap();
let ptr = raw::pkg_cache_find_name(self.ptr, name.as_ptr());
PkgIterator::new(self, ptr)
let ptr = raw::pkg_cache_find_name(lock.ptr, name.as_ptr());
PkgIterator::new(lock, ptr)
}
}
@ -48,11 +55,12 @@ impl Cache {
///
/// The returned iterator will either be at the end, or at a matching package.
pub fn find_by_name_arch(&mut self, name: &str, arch: &str) -> CIterator<PkgIterator> {
let lock = self.ptr.lock().unwrap();
unsafe {
let name = ffi::CString::new(name).unwrap();
let arch = ffi::CString::new(arch).unwrap();
let ptr = raw::pkg_cache_find_name_arch(self.ptr, name.as_ptr(), arch.as_ptr());
PkgIterator::new(self, ptr)
let ptr = raw::pkg_cache_find_name_arch(lock.ptr, name.as_ptr(), arch.as_ptr());
PkgIterator::new(lock, ptr)
}
}
@ -75,7 +83,8 @@ impl Cache {
let left = ffi::CString::new(left).unwrap();
let right = ffi::CString::new(right).unwrap();
raw::pkg_cache_compare_versions(self.ptr, left.as_ptr(), right.as_ptr()).cmp(&0)
let lock = self.ptr.lock().unwrap();
raw::pkg_cache_compare_versions(lock.ptr, left.as_ptr(), right.as_ptr()).cmp(&0)
}
}
}
@ -83,12 +92,12 @@ impl Cache {
/// An "iterator"/pointer to a point in a package list.
#[derive(Debug)]
pub struct PkgIterator<'c> {
cache: &'c Cache,
cache: MutexGuard<'c, raw::CacheHolder>,
ptr: raw::PPkgIterator,
}
impl<'c> PkgIterator<'c> {
fn new(cache: &'c Cache, ptr: raw::PCache) -> CIterator<Self> {
fn new(cache: MutexGuard<'c, raw::CacheHolder>, ptr: raw::PCache) -> CIterator<Self> {
CIterator {
first: true,
raw: PkgIterator { cache, ptr },