Context utilities in Rust
WARN: master branch is deprecated, please migrate to 1.0 branch.
[dependencies]
context = "*"or use the dev version on master
[dependencies.context]
git = "https://github.com/zonyitoo/context-rs.git"#![feature(fnbox)]externcrate context;externcrate libc;use std::mem;use std::boxed::FnBox;use context::{Context,Stack};constSTACK_SIZE:usize = 2*1024*1024;// 2MBextern"C"fninit_fn(arg:usize,f:*mut libc::c_void) -> ! {// Transmute it back to the Box<Box<FnBox()>>{let func:Box<Box<FnBox()>> = unsafe{Box::from_raw(f as*mutBox<FnBox()>)};// Call itfunc();// The `func` must be destroyed here,// or it will cause memory leak.}// The argument is the context of the main functionlet ctx:&Context = unsafe{ mem::transmute(arg)};// Switch back to the main function and will never comeback hereContext::load(ctx);unreachable!("Should never comeback");}fnmain(){// Initialize an empty contextletmut cur = Context::empty();let callback:Box<FnBox()> = Box::new(move|| {println!("Inside your function!");});letmut stk = Stack::new(STACK_SIZE).unwrap();let ctx = Context::new(init_fn,unsafe{ mem::transmute(&cur)},Box::into_raw(Box::new(callback))as*mut libc::c_void,&mut stk);println!("Before switch");// Switch!Context::swap(&mut cur,&ctx);println!("Back to main function");}Use cargo run --example simple to run this code snippet.
You have to drop the boxed function inside the initialize function!!
The resources allocated inside the initialize function must be released before the last context switch.
If you context switch inside your callback function, if you decided not to come back, you must release all your resources allocated inside your function.
This crate supports platforms in
- arm
- i686
- mips
- mipsel
- x86_64
The assembly code is in AT&T-style, so currently it only supports
*-gnutarget on Windows.