pub fn batch(f: impl FnOnce()) -> Vec<Error>Expand description
Runs f, then applies the enables and disables it made on this thread in
one transaction, so other threads are suspended once rather than per patch.
Inside f, enable and disable on a Hook or
Injection are queued and return Ok at once, and
is_enabled still reports the old state. The last change queued for a
patch wins, a nested batch joins the outer one, and other threads aren’t
affected. If f panics, the queue is still applied before the panic goes on.
Returns an error, naming the address, for each change that couldn’t be applied. If applying them together fails, each is retried alone, so one bad patch doesn’t hold back the rest.
§Examples
use imping_hook::Injection;
let mut injections = Vec::new();
for target in targets() {
// SAFETY: each target is an instruction start of a function this
// program owns, and a `nop` changes nothing.
injections.push(unsafe { Injection::at(target).code(&[0x90]).install() }.unwrap());
}
let failed = imping_hook::batch(|| {
for injection in &injections {
injection.enable().expect("queued");
}
});
assert!(failed.is_empty());