[libvirt] [rust PATCH v2 2/5] libvirt-rust: stream: add more functions in stream
Sahid Orentino Ferdjaoui
sahid.ferdjaoui at canonical.com
Fri Jan 10 11:46:33 UTC 2020
On Tue, Dec 24, 2019 at 12:12:52AM -0700, Zixing Liu wrote:
> * added virStreamEventAddCallback function
> * added new types: StreamEventCallback and FreeCallback
> * added new field: callback for storing event callback
> * drop: will drop the Box<callback> if any
> * added wrapper event_callback for easier callback authoring for the
> user (so that closures with Fn or FnMut references could be used)
> * added padding function event_free to just makes it compile (Rust
> should not need this, because Rust sticks to RAII)
>
> Signed-off-by: Zixing Liu <liushuyu at aosc.io>
> ---
> src/stream.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
Reviewed-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui at canonical.com>
> diff --git a/src/stream.rs b/src/stream.rs
> index de272ab..1ffd186 100644
> --- a/src/stream.rs
> +++ b/src/stream.rs
> @@ -47,6 +47,12 @@ extern "C" {
> fn virStreamFree(c: sys::virStreamPtr) -> libc::c_int;
> fn virStreamAbort(c: sys::virStreamPtr) -> libc::c_int;
> fn virStreamFinish(c: sys::virStreamPtr) -> libc::c_int;
> + fn virStreamEventAddCallback(c: sys::virStreamPtr,
> + event: libc::c_int,
> + callback: StreamEventCallback,
> + opaque: *const libc::c_void,
> + ff: FreeCallback)
> + -> libc::c_int;
> fn virStreamEventUpdateCallback(c: sys::virStreamPtr,
> events: libc::c_int) -> libc::c_int;
> fn virStreamEventRemoveCallback(c: sys::virStreamPtr) -> libc::c_int;
> @@ -61,9 +67,26 @@ pub const VIR_STREAM_EVENT_HANGUP: StreamEventType = (1 << 3);
> pub type StreamFlags = self::libc::c_uint;
> pub const VIR_STREAM_NONBLOCK: StreamFlags = (1 << 0);
>
> -#[derive(Debug)]
> +pub type StreamEventCallback = extern "C" fn(sys::virStreamPtr, libc::c_int, *const libc::c_void);
> +pub type FreeCallback = extern "C" fn(*mut libc::c_void);
> +
> +// wrapper for callbacks
> +extern "C" fn event_callback(c: sys::virStreamPtr, flags: libc::c_int, opaque: *const libc::c_void) {
> + let flags = flags as StreamFlags;
> + let shadow_self = unsafe {
> + &mut*(opaque as *mut Stream)
> + };
> + if let Some(callback) = &mut shadow_self.callback {
> + callback(&Stream::from_ptr(c), flags);
> + }
> +}
> +
> +extern "C" fn event_free(_opaque: *mut libc::c_void) {}
> +
> +// #[derive(Debug)]
This line can be removed.
> pub struct Stream {
> ptr: Option<sys::virStreamPtr>,
> + callback: Option<Box<dyn FnMut(&Stream, StreamEventType)>>,
> }
>
> impl Drop for Stream {
> @@ -75,6 +98,13 @@ impl Drop for Stream {
> e.message)
> }
> }
> + if self.callback.is_some() {
> + if let Err(e) = self.event_remove_callback() {
> + panic!("Unable to remove event callback for Stream, code {}, message: {}",
> + e.code,
> + e.message)
> + }
> + }
> }
> }
>
> @@ -90,7 +120,7 @@ impl Stream {
> }
>
> pub fn from_ptr(ptr: sys::virStreamPtr) -> Stream {
> - Stream { ptr: Some(ptr) }
> + Stream { ptr: Some(ptr), callback: None }
> }
>
> pub fn as_ptr(&self) -> sys::virStreamPtr {
> @@ -147,6 +177,18 @@ impl Stream {
> usize::try_from(ret).map_err(|_| Error::new())
> }
>
> + pub fn event_add_callback<F: 'static + FnMut(&Stream, StreamEventType)>(&mut self, events: StreamEventType, cb: F) -> Result<(), Error> {
> + let ret = unsafe {
> + let ptr = &*self as *const _ as *const _;
> + virStreamEventAddCallback(self.as_ptr(), events as libc::c_int, event_callback, ptr, event_free)
> + };
> + if ret == -1 {
> + return Err(Error::new());
> + }
> + self.callback = Some(Box::new(cb));
> + return Ok(());
> + }
> +
> pub fn event_update_callback(&self, events: StreamEventType) -> Result<(), Error> {
> let ret = unsafe {
> virStreamEventUpdateCallback(self.as_ptr(), events as libc::c_int)
> --
> 2.24.1
More information about the libvir-list
mailing list