Andrea Ciliberti
3 years ago
10 changed files with 133 additions and 239 deletions
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
use crate::Error; |
||||
use std::sync::Mutex; |
||||
pub(crate) struct ServiceReference { |
||||
counter: &'static Mutex<usize>, |
||||
close: Box<dyn Fn()>, |
||||
} |
||||
|
||||
impl ServiceReference { |
||||
pub fn new<S, E>( |
||||
counter: &'static Mutex<usize>, |
||||
allow_multiple: bool, |
||||
start: S, |
||||
close: E, |
||||
) -> crate::Result<Self> |
||||
where |
||||
S: FnOnce() -> crate::Result<()>, |
||||
E: Fn() + 'static, |
||||
{ |
||||
let mut value = counter.lock().unwrap(); // todo: handle poisoning
|
||||
|
||||
if *value == 0 { |
||||
start()?; |
||||
} else if !allow_multiple { |
||||
return Err(Error::ServiceAlreadyActive); |
||||
} |
||||
|
||||
*value += 1; |
||||
|
||||
Ok(Self { |
||||
counter, |
||||
close: Box::new(close), |
||||
}) |
||||
} |
||||
} |
||||
|
||||
impl Drop for ServiceReference { |
||||
fn drop(&mut self) { |
||||
let mut value = self.counter.lock().unwrap(); // should probably handle poisoning - could just map_err to ignore it.
|
||||
*value -= 1; |
||||
if *value == 0 { |
||||
(self.close)(); |
||||
} |
||||
} |
||||
} |
@ -1,66 +1,35 @@
@@ -1,66 +1,35 @@
|
||||
// TODO: Implement remaining functions
|
||||
|
||||
use once_cell::sync::Lazy; |
||||
use std::sync::Mutex; |
||||
|
||||
use crate::services::ServiceReference; |
||||
|
||||
#[non_exhaustive] |
||||
pub struct SslC { |
||||
_service_handler: ServiceReference, |
||||
} |
||||
|
||||
static SSLC_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0)); |
||||
pub struct SslC(()); |
||||
|
||||
impl SslC { |
||||
/// Initialize sslc
|
||||
pub fn init() -> crate::Result<Self> { |
||||
let _service_handler = ServiceReference::new( |
||||
&SSLC_ACTIVE, |
||||
true, |
||||
|| { |
||||
let r = unsafe { ctru_sys::sslcInit(0) }; |
||||
if r < 0 { |
||||
return Err(r.into()); |
||||
} |
||||
|
||||
Ok(()) |
||||
}, |
||||
|| unsafe { |
||||
ctru_sys::sslcExit(); |
||||
}, |
||||
)?; |
||||
|
||||
Ok(Self { _service_handler }) |
||||
unsafe { |
||||
let r = ctru_sys::sslcInit(0); |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(SslC(())) |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Fill `buf` with `buf.len()` random bytes
|
||||
pub fn generate_random_data(&self, buf: &mut [u8]) -> crate::Result<()> { |
||||
let r = unsafe { ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32) }; |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(()) |
||||
unsafe { |
||||
let r = ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32); |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(()) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
#[test] |
||||
fn sslc_duplicate() { |
||||
let _sslc = SslC::init().unwrap(); |
||||
|
||||
let value = *SSLC_ACTIVE.lock().unwrap(); |
||||
|
||||
assert_eq!(value, 1); |
||||
|
||||
drop(_sslc); |
||||
|
||||
let value = *SSLC_ACTIVE.lock().unwrap(); |
||||
|
||||
assert_eq!(value, 0); |
||||
impl Drop for SslC { |
||||
fn drop(&mut self) { |
||||
unsafe { ctru_sys::sslcExit() }; |
||||
} |
||||
} |
||||
|
@ -1,53 +1,20 @@
@@ -1,53 +1,20 @@
|
||||
use once_cell::sync::Lazy; |
||||
use std::sync::Mutex; |
||||
|
||||
use crate::services::ServiceReference; |
||||
|
||||
#[non_exhaustive] |
||||
pub struct Srv { |
||||
_service_handler: ServiceReference, |
||||
} |
||||
|
||||
static SRV_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0)); |
||||
pub struct Srv(()); |
||||
|
||||
impl Srv { |
||||
pub fn init() -> crate::Result<Self> { |
||||
let _service_handler = ServiceReference::new( |
||||
&SRV_ACTIVE, |
||||
true, |
||||
|| { |
||||
let r = unsafe { ctru_sys::srvInit() }; |
||||
if r < 0 { |
||||
return Err(r.into()); |
||||
} |
||||
|
||||
Ok(()) |
||||
}, |
||||
|| unsafe { |
||||
ctru_sys::srvExit(); |
||||
}, |
||||
)?; |
||||
|
||||
Ok(Self { _service_handler }) |
||||
pub fn init() -> crate::Result<Srv> { |
||||
unsafe { |
||||
let r = ctru_sys::srvInit(); |
||||
if r < 0 { |
||||
Err(r.into()) |
||||
} else { |
||||
Ok(Srv(())) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
#[test] |
||||
fn srv_duplicate() { |
||||
let _srv = Srv::init().unwrap(); |
||||
|
||||
let value = *SRV_ACTIVE.lock().unwrap(); |
||||
|
||||
assert_eq!(value, 1); |
||||
|
||||
drop(_srv); |
||||
|
||||
let value = *SRV_ACTIVE.lock().unwrap(); |
||||
|
||||
assert_eq!(value, 0); |
||||
impl Drop for Srv { |
||||
fn drop(&mut self) { |
||||
unsafe { ctru_sys::srvExit() }; |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue