refactor(compress): move CDict construction policy to Rust
Move advanced and static CDict construction ordering into Rust while keeping private workspace layout, object initialization, dictionary loading, and allocator leaves in C callbacks. The Rust policy now validates parameters and memory, computes the workspace contract, sequences allocation/reservation and initialization, and preserves failure cleanup for both dynamic and static workspaces. Add callback-order, allocation-failure, reservation-failure, and initializer-failure tests around the ABI projections. Test Plan: - `cargo fmt --manifest-path rust/Cargo.toml --all -- --check` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo build --manifest-path rust/Cargo.toml --release`
This commit is contained in:
@@ -835,16 +835,10 @@ type CreateCDictAdvancedWorkspaceSizeFn = unsafe extern "C" fn(
|
||||
c_int,
|
||||
) -> usize;
|
||||
type CreateCDictAdvancedAllocateFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
|
||||
type CreateCDictAdvancedCreateFn = unsafe extern "C" fn(
|
||||
*mut c_void,
|
||||
*mut c_void,
|
||||
usize,
|
||||
usize,
|
||||
c_int,
|
||||
*const ZSTD_compressionParameters,
|
||||
c_int,
|
||||
c_int,
|
||||
) -> *mut c_void;
|
||||
type CreateCDictAdvancedCreateWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void, usize);
|
||||
type CreateCDictAdvancedReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||
type CreateCDictAdvancedMoveWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
|
||||
type CreateCDictAdvancedInitializeFn = unsafe extern "C" fn(*mut c_void, *mut c_void, c_int);
|
||||
type CreateCDictAdvancedInitFn = unsafe extern "C" fn(
|
||||
*mut c_void,
|
||||
*mut c_void,
|
||||
@@ -877,7 +871,10 @@ pub struct ZSTD_rust_createCDictAdvancedState {
|
||||
validate_custom_mem: CreateCDictAdvancedValidateCustomMemFn,
|
||||
workspace_size: CreateCDictAdvancedWorkspaceSizeFn,
|
||||
allocate: CreateCDictAdvancedAllocateFn,
|
||||
create: CreateCDictAdvancedCreateFn,
|
||||
create_workspace: CreateCDictAdvancedCreateWorkspaceFn,
|
||||
reserve_object: CreateCDictAdvancedReserveObjectFn,
|
||||
move_workspace: CreateCDictAdvancedMoveWorkspaceFn,
|
||||
initialize: CreateCDictAdvancedInitializeFn,
|
||||
init: CreateCDictAdvancedInitFn,
|
||||
free_workspace: CreateCDictAdvancedFreeWorkspaceFn,
|
||||
free: CreateCDictAdvancedFreeFn,
|
||||
@@ -917,28 +914,41 @@ const _: () = {
|
||||
== size_of::<[usize; 7]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, create)
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, create_workspace)
|
||||
== size_of::<[usize; 8]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, init)
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, reserve_object)
|
||||
== size_of::<[usize; 9]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, free_workspace)
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, move_workspace)
|
||||
== size_of::<[usize; 10]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, free)
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, initialize)
|
||||
== size_of::<[usize; 11]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
size_of::<ZSTD_rust_createCDictAdvancedState>()
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, init)
|
||||
== size_of::<[usize; 12]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, free_workspace)
|
||||
== size_of::<[usize; 13]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedState, free)
|
||||
== size_of::<[usize; 14]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
assert!(
|
||||
size_of::<ZSTD_rust_createCDictAdvancedState>()
|
||||
== size_of::<[usize; 15]>() + size_of::<[u32; 2]>()
|
||||
);
|
||||
};
|
||||
|
||||
/// Prepare advanced-CDict parameters and run the C-owned construction path.
|
||||
/// Prepare advanced-CDict parameters and run the C-owned construction leaves
|
||||
/// in their original allocation, workspace, and initialization order.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_createCDictAdvanced(
|
||||
state: *const ZSTD_rust_createCDictAdvancedState,
|
||||
@@ -991,23 +1001,20 @@ pub unsafe extern "C" fn ZSTD_rust_createCDictAdvanced(
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let cdict = unsafe {
|
||||
(state.create)(
|
||||
state.callback_context,
|
||||
workspace,
|
||||
workspace_size,
|
||||
dict_size,
|
||||
dict_load_method,
|
||||
state.cparams,
|
||||
*state.use_row_match_finder,
|
||||
*state.enable_dedicated_dict_search,
|
||||
)
|
||||
};
|
||||
unsafe {
|
||||
(state.create_workspace)(state.callback_context, workspace, workspace_size);
|
||||
}
|
||||
let cdict = unsafe { (state.reserve_object)(state.callback_context) };
|
||||
if cdict.is_null() {
|
||||
unsafe { (state.free_workspace)(state.callback_context, workspace) };
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
(state.move_workspace)(state.callback_context, cdict);
|
||||
(state.initialize)(state.callback_context, cdict, *state.use_row_match_finder);
|
||||
}
|
||||
|
||||
let init_result = unsafe {
|
||||
(state.init)(
|
||||
state.callback_context,
|
||||
@@ -1068,19 +1075,27 @@ pub unsafe extern "C" fn ZSTD_rust_freeCDict(state: *const ZSTD_rust_freeCDictSt
|
||||
0
|
||||
}
|
||||
|
||||
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||
type InitStaticCDictCreateWorkspaceFn = unsafe extern "C" fn(*mut c_void);
|
||||
type InitStaticCDictReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||
type InitStaticCDictMoveWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
|
||||
type InitStaticCDictInitializeFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
|
||||
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void;
|
||||
|
||||
/// Explicit projection for the public `ZSTD_initStaticCDict` wrapper.
|
||||
///
|
||||
/// Rust owns workspace pointer/alignment validation, minimum-size validation,
|
||||
/// and callback ordering. C retains the private static-workspace layout and
|
||||
/// dictionary initialization behind one callback.
|
||||
/// dictionary initialization behind narrow callbacks.
|
||||
#[repr(C)]
|
||||
pub struct ZSTD_rust_initStaticCDictState {
|
||||
callback_context: *mut c_void,
|
||||
workspace: *mut c_void,
|
||||
workspace_size: usize,
|
||||
needed_size: usize,
|
||||
create_workspace: InitStaticCDictCreateWorkspaceFn,
|
||||
reserve_object: InitStaticCDictReserveObjectFn,
|
||||
move_workspace: InitStaticCDictMoveWorkspaceFn,
|
||||
initialize: InitStaticCDictInitializeFn,
|
||||
init: InitStaticCDictFn,
|
||||
}
|
||||
|
||||
@@ -1089,8 +1104,12 @@ const _: () = {
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace) == size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace_size) == 2 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, needed_size) == 3 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, init) == 4 * size_of::<usize>());
|
||||
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 5]>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, create_workspace) == 4 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, reserve_object) == 5 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, move_workspace) == 6 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, initialize) == 7 * size_of::<usize>());
|
||||
assert!(offset_of!(ZSTD_rust_initStaticCDictState, init) == usize::BITS as usize);
|
||||
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 9]>());
|
||||
};
|
||||
|
||||
/// Validate static CDict workspace ownership before entering the C leaf.
|
||||
@@ -1109,7 +1128,18 @@ pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
||||
{
|
||||
return ptr::null_mut();
|
||||
}
|
||||
unsafe { (state.init)(state.callback_context) }
|
||||
unsafe {
|
||||
(state.create_workspace)(state.callback_context);
|
||||
}
|
||||
let cdict = unsafe { (state.reserve_object)(state.callback_context) };
|
||||
if cdict.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
unsafe {
|
||||
(state.move_workspace)(state.callback_context, cdict);
|
||||
(state.initialize)(state.callback_context, cdict);
|
||||
(state.init)(state.callback_context, cdict)
|
||||
}
|
||||
}
|
||||
|
||||
type CompressBeginUsingDictBeginFn =
|
||||
@@ -4587,13 +4617,12 @@ mod tests {
|
||||
workspace_size_enable_dedicated_dict_search: c_int,
|
||||
allocated_workspace: *mut c_void,
|
||||
allocated_workspace_size: usize,
|
||||
create_workspace: *mut c_void,
|
||||
create_workspace_size: usize,
|
||||
create_dict_size: usize,
|
||||
create_dict_load_method: c_int,
|
||||
cparams: *const ZSTD_compressionParameters,
|
||||
created_workspace: *mut c_void,
|
||||
created_workspace_size: usize,
|
||||
reserved_cdict: *mut c_void,
|
||||
moved_cdict: *mut c_void,
|
||||
initialized_cdict: *mut c_void,
|
||||
use_row_match_finder: c_int,
|
||||
enable_dedicated_dict_search: c_int,
|
||||
cdict_result: *mut c_void,
|
||||
init_cdict: *mut c_void,
|
||||
init_dict: *const c_void,
|
||||
@@ -4642,28 +4671,46 @@ mod tests {
|
||||
probe.allocated_workspace
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_test_create(
|
||||
unsafe extern "C" fn create_cdict_advanced_test_create_workspace(
|
||||
context: *mut c_void,
|
||||
workspace: *mut c_void,
|
||||
workspace_size: usize,
|
||||
dict_size: usize,
|
||||
dict_load_method: c_int,
|
||||
cparams: *const ZSTD_compressionParameters,
|
||||
use_row_match_finder: c_int,
|
||||
enable_dedicated_dict_search: c_int,
|
||||
) {
|
||||
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
|
||||
probe.events.push("create_workspace");
|
||||
probe.created_workspace = workspace;
|
||||
probe.created_workspace_size = workspace_size;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_test_reserve_object(
|
||||
context: *mut c_void,
|
||||
) -> *mut c_void {
|
||||
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
|
||||
probe.events.push("create");
|
||||
probe.create_workspace = workspace;
|
||||
probe.create_workspace_size = workspace_size;
|
||||
probe.create_dict_size = dict_size;
|
||||
probe.create_dict_load_method = dict_load_method;
|
||||
probe.cparams = cparams;
|
||||
probe.use_row_match_finder = use_row_match_finder;
|
||||
probe.enable_dedicated_dict_search = enable_dedicated_dict_search;
|
||||
probe.events.push("reserve_object");
|
||||
probe.reserved_cdict = probe.cdict_result;
|
||||
probe.cdict_result
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_test_move_workspace(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
) {
|
||||
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
|
||||
probe.events.push("move_workspace");
|
||||
probe.moved_cdict = cdict;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_test_initialize(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
use_row_match_finder: c_int,
|
||||
) {
|
||||
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
|
||||
probe.events.push("initialize");
|
||||
probe.initialized_cdict = cdict;
|
||||
probe.use_row_match_finder = use_row_match_finder;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_test_init(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
@@ -4731,7 +4778,10 @@ mod tests {
|
||||
validate_custom_mem: create_cdict_advanced_test_validate_custom_mem,
|
||||
workspace_size: create_cdict_advanced_test_workspace_size,
|
||||
allocate: create_cdict_advanced_test_allocate,
|
||||
create: create_cdict_advanced_test_create,
|
||||
create_workspace: create_cdict_advanced_test_create_workspace,
|
||||
reserve_object: create_cdict_advanced_test_reserve_object,
|
||||
move_workspace: create_cdict_advanced_test_move_workspace,
|
||||
initialize: create_cdict_advanced_test_initialize,
|
||||
init: create_cdict_advanced_test_init,
|
||||
free_workspace: create_cdict_advanced_test_free_workspace,
|
||||
free: create_cdict_advanced_test_free,
|
||||
@@ -4782,7 +4832,16 @@ mod tests {
|
||||
assert_eq!(result, probe.cdict_result);
|
||||
assert_eq!(
|
||||
probe.events,
|
||||
["validate", "workspace_size", "allocate", "create", "init"]
|
||||
[
|
||||
"validate",
|
||||
"workspace_size",
|
||||
"allocate",
|
||||
"create_workspace",
|
||||
"reserve_object",
|
||||
"move_workspace",
|
||||
"initialize",
|
||||
"init"
|
||||
]
|
||||
);
|
||||
assert_eq!(probe.workspace_size_dict_size, dict.len());
|
||||
assert_eq!(probe.workspace_size_dict_load_method, ZSTD_DLM_BY_REF);
|
||||
@@ -4796,16 +4855,12 @@ mod tests {
|
||||
enable_dedicated_dict_search
|
||||
);
|
||||
assert_eq!(probe.allocated_workspace_size, 123);
|
||||
assert_eq!(probe.create_workspace, probe.allocated_workspace);
|
||||
assert_eq!(probe.create_workspace_size, 123);
|
||||
assert_eq!(probe.create_dict_size, dict.len());
|
||||
assert_eq!(probe.create_dict_load_method, ZSTD_DLM_BY_REF);
|
||||
assert_eq!(probe.cparams, &cparams);
|
||||
assert_eq!(probe.created_workspace, probe.allocated_workspace);
|
||||
assert_eq!(probe.created_workspace_size, 123);
|
||||
assert_eq!(probe.reserved_cdict, probe.cdict_result);
|
||||
assert_eq!(probe.moved_cdict, probe.cdict_result);
|
||||
assert_eq!(probe.initialized_cdict, probe.cdict_result);
|
||||
assert_eq!(probe.use_row_match_finder, use_row_match_finder);
|
||||
assert_eq!(
|
||||
probe.enable_dedicated_dict_search,
|
||||
enable_dedicated_dict_search
|
||||
);
|
||||
assert_eq!(probe.init_cdict, probe.cdict_result);
|
||||
assert_eq!(probe.init_dict, dict.as_ptr().cast());
|
||||
assert_eq!(probe.init_dict_size, dict.len());
|
||||
@@ -4838,7 +4893,7 @@ mod tests {
|
||||
|
||||
assert!(result.is_null());
|
||||
assert_eq!(probe.events, ["validate"]);
|
||||
assert!(probe.create_workspace.is_null());
|
||||
assert!(probe.created_workspace.is_null());
|
||||
assert!(probe.free_workspace.is_null());
|
||||
assert!(probe.free_cdict.is_null());
|
||||
}
|
||||
@@ -4870,13 +4925,13 @@ mod tests {
|
||||
assert!(result.is_null());
|
||||
assert_eq!(probe.events, ["validate", "workspace_size", "allocate"]);
|
||||
assert_eq!(probe.allocated_workspace_size, 321);
|
||||
assert!(probe.create_workspace.is_null());
|
||||
assert!(probe.created_workspace.is_null());
|
||||
assert!(probe.free_workspace.is_null());
|
||||
assert!(probe.free_cdict.is_null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_cdict_advanced_frees_workspace_after_creation_failure() {
|
||||
fn create_cdict_advanced_frees_workspace_after_reservation_failure() {
|
||||
let workspace = ptr::dangling_mut::<c_void>();
|
||||
let mut probe = CreateCDictAdvancedProbe {
|
||||
custom_mem_valid: 1,
|
||||
@@ -4908,13 +4963,13 @@ mod tests {
|
||||
"validate",
|
||||
"workspace_size",
|
||||
"allocate",
|
||||
"create",
|
||||
"create_workspace",
|
||||
"reserve_object",
|
||||
"free_workspace"
|
||||
]
|
||||
);
|
||||
assert_eq!(probe.create_workspace, workspace);
|
||||
assert_eq!(probe.create_workspace_size, 321);
|
||||
assert_eq!(probe.create_dict_size, 0);
|
||||
assert_eq!(probe.created_workspace, workspace);
|
||||
assert_eq!(probe.created_workspace_size, 321);
|
||||
assert_eq!(probe.free_workspace, workspace);
|
||||
assert!(probe.free_cdict.is_null());
|
||||
}
|
||||
@@ -4955,14 +5010,19 @@ mod tests {
|
||||
"validate",
|
||||
"workspace_size",
|
||||
"allocate",
|
||||
"create",
|
||||
"create_workspace",
|
||||
"reserve_object",
|
||||
"move_workspace",
|
||||
"initialize",
|
||||
"init",
|
||||
"free"
|
||||
]
|
||||
);
|
||||
assert_eq!(probe.create_workspace, workspace);
|
||||
assert_eq!(probe.create_workspace_size, 321);
|
||||
assert_eq!(probe.create_dict_size, 0);
|
||||
assert_eq!(probe.created_workspace, workspace);
|
||||
assert_eq!(probe.created_workspace_size, 321);
|
||||
assert_eq!(probe.reserved_cdict, cdict);
|
||||
assert_eq!(probe.moved_cdict, cdict);
|
||||
assert_eq!(probe.initialized_cdict, cdict);
|
||||
assert!(probe.free_workspace.is_null());
|
||||
assert_eq!(probe.free_cdict, cdict);
|
||||
}
|
||||
@@ -5033,12 +5093,53 @@ mod tests {
|
||||
#[derive(Default)]
|
||||
struct InitStaticCDictProbe {
|
||||
events: Vec<&'static str>,
|
||||
reserved_cdict: *mut c_void,
|
||||
moved_cdict: *mut c_void,
|
||||
initialized_cdict: *mut c_void,
|
||||
init_cdict: *mut c_void,
|
||||
initialized: bool,
|
||||
result: *mut c_void,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_init(context: *mut c_void) -> *mut c_void {
|
||||
unsafe extern "C" fn init_static_cdict_test_create_workspace(context: *mut c_void) {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("create_workspace");
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_reserve_object(
|
||||
context: *mut c_void,
|
||||
) -> *mut c_void {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("reserve_object");
|
||||
probe.reserved_cdict
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_move_workspace(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
) {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("move_workspace");
|
||||
probe.moved_cdict = cdict;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_initialize(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
) {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("initialize");
|
||||
probe.initialized_cdict = cdict;
|
||||
probe.initialized = true;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_init(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
) -> *mut c_void {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("init");
|
||||
probe.init_cdict = cdict;
|
||||
probe.result
|
||||
}
|
||||
|
||||
@@ -5053,6 +5154,10 @@ mod tests {
|
||||
workspace,
|
||||
workspace_size,
|
||||
needed_size,
|
||||
create_workspace: init_static_cdict_test_create_workspace,
|
||||
reserve_object: init_static_cdict_test_reserve_object,
|
||||
move_workspace: init_static_cdict_test_move_workspace,
|
||||
initialize: init_static_cdict_test_initialize,
|
||||
init: init_static_cdict_test_init,
|
||||
}
|
||||
}
|
||||
@@ -5095,7 +5200,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_calls_the_initializer_after_workspace_validation() {
|
||||
let cdict = ptr::dangling_mut::<c_void>();
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
reserved_cdict: cdict,
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
@@ -5110,7 +5217,72 @@ mod tests {
|
||||
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
||||
|
||||
assert_eq!(result, probe.result);
|
||||
assert_eq!(probe.events, ["init"]);
|
||||
assert_eq!(
|
||||
probe.events,
|
||||
[
|
||||
"create_workspace",
|
||||
"reserve_object",
|
||||
"move_workspace",
|
||||
"initialize",
|
||||
"init"
|
||||
]
|
||||
);
|
||||
assert_eq!(probe.moved_cdict, cdict);
|
||||
assert_eq!(probe.initialized_cdict, cdict);
|
||||
assert_eq!(probe.init_cdict, cdict);
|
||||
assert!(probe.initialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_stops_after_object_reservation_failure() {
|
||||
let mut probe = InitStaticCDictProbe::default();
|
||||
let mut workspace = [0usize; 1];
|
||||
let state = init_static_cdict_test_state(
|
||||
&mut probe,
|
||||
workspace.as_mut_ptr().cast(),
|
||||
size_of_val(&workspace),
|
||||
0,
|
||||
);
|
||||
|
||||
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
||||
|
||||
assert!(result.is_null());
|
||||
assert_eq!(probe.events, ["create_workspace", "reserve_object"]);
|
||||
assert!(probe.moved_cdict.is_null());
|
||||
assert!(!probe.initialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_propagates_initializer_failure_after_setup() {
|
||||
let cdict = ptr::dangling_mut::<c_void>();
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
reserved_cdict: cdict,
|
||||
result: ptr::null_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut workspace = [0usize; 1];
|
||||
let state = init_static_cdict_test_state(
|
||||
&mut probe,
|
||||
workspace.as_mut_ptr().cast(),
|
||||
size_of_val(&workspace),
|
||||
size_of_val(&workspace),
|
||||
);
|
||||
|
||||
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
||||
|
||||
assert!(result.is_null());
|
||||
assert_eq!(probe.init_cdict, cdict);
|
||||
assert!(probe.initialized);
|
||||
assert_eq!(
|
||||
probe.events,
|
||||
[
|
||||
"create_workspace",
|
||||
"reserve_object",
|
||||
"move_workspace",
|
||||
"initialize",
|
||||
"init"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user