Skip to content

Commit 6118931

Browse files
committed
aud_io: Add GlobalOptions for allocations
1 parent 13ef4d6 commit 6118931

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use std::cell::UnsafeCell;
2+
3+
thread_local! {
4+
static GLOBAL_OPTIONS: UnsafeCell<GlobalOptions> = UnsafeCell::new(GlobalOptions::default());
5+
}
6+
7+
pub(crate) unsafe fn global_options() -> &'static GlobalOptions {
8+
GLOBAL_OPTIONS.with(|global_options| unsafe { &*global_options.get() })
9+
}
10+
11+
/// Options that control all interactions with `aud_io` for the current thread
12+
///
13+
/// # Examples
14+
///
15+
/// ```rust
16+
/// use aud_io::config::{GlobalOptions, apply_global_options};
17+
///
18+
/// // I want to double the allocation limit
19+
/// let global_options = GlobalOptions::new().allocation_limit(GlobalOptions::DEFAULT_ALLOCATION_LIMIT * 2);
20+
/// apply_global_options(global_options);
21+
/// ```
22+
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
23+
#[non_exhaustive]
24+
pub struct GlobalOptions {
25+
pub(crate) allocation_limit: usize,
26+
}
27+
28+
impl GlobalOptions {
29+
/// Default allocation limit for any single allocation
30+
pub const DEFAULT_ALLOCATION_LIMIT: usize = 16 * 1024 * 1024;
31+
32+
/// Creates a new `GlobalOptions`, alias for `Default` implementation
33+
///
34+
/// See also: [`GlobalOptions::default`]
35+
///
36+
/// # Examples
37+
///
38+
/// ```rust
39+
/// use aud_io::config::GlobalOptions;
40+
///
41+
/// let global_options = GlobalOptions::new();
42+
/// ```
43+
#[must_use]
44+
pub const fn new() -> Self {
45+
Self {
46+
allocation_limit: Self::DEFAULT_ALLOCATION_LIMIT,
47+
}
48+
}
49+
50+
/// The maximum number of bytes to allocate for any single allocation
51+
///
52+
/// This is a safety measure to prevent allocating too much memory for a single allocation. If an allocation
53+
/// exceeds this limit, the allocator will return [`AudioError::TooMuchData`](crate::error::AudioError::TooMuchData).
54+
///
55+
/// # Examples
56+
///
57+
/// ```rust
58+
/// use aud_io::config::{GlobalOptions, apply_global_options};
59+
///
60+
/// // I have files with gigantic images, I'll double the allocation limit!
61+
/// let global_options = GlobalOptions::new().allocation_limit(GlobalOptions::DEFAULT_ALLOCATION_LIMIT * 2);
62+
/// apply_global_options(global_options);
63+
/// ```
64+
pub fn allocation_limit(&mut self, allocation_limit: usize) -> Self {
65+
self.allocation_limit = allocation_limit;
66+
*self
67+
}
68+
}
69+
70+
impl Default for GlobalOptions {
71+
/// The default implementation for `GlobalOptions`
72+
///
73+
/// The defaults are as follows:
74+
///
75+
/// ```rust,ignore
76+
/// GlobalOptions {
77+
/// allocation_limit: Self::DEFAULT_ALLOCATION_LIMIT,
78+
/// }
79+
/// ```
80+
fn default() -> Self {
81+
Self::new()
82+
}
83+
}
84+
85+
/// Applies the given `GlobalOptions` to the current thread
86+
///
87+
/// # Examples
88+
///
89+
/// ```rust
90+
/// use aud_io::config::{GlobalOptions, apply_global_options};
91+
///
92+
/// // I want to double the allocation limit
93+
/// let global_options = GlobalOptions::new().allocation_limit(GlobalOptions::DEFAULT_ALLOCATION_LIMIT * 2);
94+
/// apply_global_options(global_options);
95+
/// ```
96+
pub fn apply_global_options(options: GlobalOptions) {
97+
GLOBAL_OPTIONS.with(|global_options| unsafe {
98+
*global_options.get() = options;
99+
});
100+
}

aud_io/src/config/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod global_options;
2+
3+
pub use global_options::*;

aud_io/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ pub mod error;
33
pub(crate) mod macros;
44
pub mod math;
55
pub mod io;
6+
pub mod config;

lofty/src/config/global_options.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct GlobalOptions {
2929

3030
impl GlobalOptions {
3131
/// Default allocation limit for any single tag item
32-
pub const DEFAULT_ALLOCATION_LIMIT: usize = 16 * 1024 * 1024;
32+
pub const DEFAULT_ALLOCATION_LIMIT: usize = aud_io::config::GlobalOptions::DEFAULT_ALLOCATION_LIMIT;
3333

3434
/// Creates a new `GlobalOptions`, alias for `Default` implementation
3535
///
@@ -131,6 +131,12 @@ impl Default for GlobalOptions {
131131
}
132132
}
133133

134+
impl From<GlobalOptions> for aud_io::config::GlobalOptions {
135+
fn from(options: GlobalOptions) -> Self {
136+
aud_io::config::GlobalOptions::new().allocation_limit(options.allocation_limit)
137+
}
138+
}
139+
134140
/// Applies the given `GlobalOptions` to the current thread
135141
///
136142
/// # Examples
@@ -143,6 +149,9 @@ impl Default for GlobalOptions {
143149
/// apply_global_options(global_options);
144150
/// ```
145151
pub fn apply_global_options(options: GlobalOptions) {
152+
// Propagate changes to `aud_io` as well
153+
aud_io::config::apply_global_options(options.into());
154+
146155
GLOBAL_OPTIONS.with(|global_options| unsafe {
147156
*global_options.get() = options;
148157
});

0 commit comments

Comments
 (0)