Projects
Eulaceura:Mainline:GA
corosync
_service:obs_scm:backport-rust-Improve-Rust-bin...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:backport-rust-Improve-Rust-bindings.patch of Package corosync
From 58d654261a3bbd04cb19b1ddc85d8d872f94384e Mon Sep 17 00:00:00 2001 From: Christine Caulfield <ccaulfie@redhat.com> Date: Mon, 8 Jan 2024 14:29:36 +0000 Subject: [PATCH] rust: Improve Rust bindings The big change here is that all API calls now take a &Handle rather than making a copy. This, apart from being more sensible and efficient, allows us to implment Drop on the handle so that it will call _free() when it goes out of scope. There's some jiggery-pokery with a clone flag in there now because of callbacks that can return a valid handle, and we want those to be Drop'ed sensibly. Signed-off-by: Christine Caulfield <ccaulfie@redhat.com> Reviewed-by: Jan Friesse <jfriesse@redhat.com> --- bindings/rust/src/cfg.rs | 54 +++++++++---- bindings/rust/src/cmap.rs | 76 ++++++++++++------- bindings/rust/src/cpg.rs | 56 ++++++++++---- bindings/rust/src/quorum.rs | 46 ++++++++--- bindings/rust/src/votequorum.rs | 60 ++++++++++----- bindings/rust/tests/src/bin/cfg-test.rs | 20 ++--- bindings/rust/tests/src/bin/cmap-test.rs | 34 ++++----- bindings/rust/tests/src/bin/cpg-test.rs | 16 ++-- bindings/rust/tests/src/bin/quorum-test.rs | 8 +- .../rust/tests/src/bin/votequorum-test.rs | 14 ++-- 10 files changed, 256 insertions(+), 128 deletions(-) diff --git a/bindings/rust/src/cfg.rs b/bindings/rust/src/cfg.rs index b4eecacc..5e1a0442 100644 --- a/bindings/rust/src/cfg.rs +++ b/bindings/rust/src/cfg.rs @@ -31,10 +31,35 @@ pub struct Callbacks { } /// A handle into the cfg library. returned from [initialize] and needed for all other calls -#[derive(Copy, Clone)] pub struct Handle { cfg_handle: u64, callbacks: Callbacks, + clone: bool, +} + +impl Clone for Handle { + fn clone(&self) -> Handle { + Handle { + cfg_handle: self.cfg_handle, + callbacks: self.callbacks, + clone: true, + } + } +} + +impl Drop for Handle { + fn drop(self: &mut Handle) { + if !self.clone { + let _e = finalize(self); + } + } +} + +// Clones count as equivalent +impl PartialEq for Handle { + fn eq(&self, other: &Handle) -> bool { + self.cfg_handle == other.cfg_handle + } } /// Flags for [try_shutdown] @@ -114,8 +139,9 @@ pub fn initialize(callbacks: &Callbacks) -> Result<Handle> { let rhandle = Handle { cfg_handle: handle, callbacks: *callbacks, + clone: false, }; - HANDLE_HASH.lock().unwrap().insert(handle, rhandle); + HANDLE_HASH.lock().unwrap().insert(handle, rhandle.clone()); Ok(rhandle) } else { Err(CsError::from_c(res)) @@ -124,7 +150,7 @@ pub fn initialize(callbacks: &Callbacks) -> Result<Handle> { } /// Finish with a connection to corosync, after calling this the [Handle] is invalid -pub fn finalize(handle: Handle) -> Result<()> { +pub fn finalize(handle: &Handle) -> Result<()> { let res = unsafe { ffi::corosync_cfg_finalize(handle.cfg_handle) }; if res == ffi::CS_OK { HANDLE_HASH.lock().unwrap().remove(&handle.cfg_handle); @@ -136,7 +162,7 @@ pub fn finalize(handle: Handle) -> Result<()> { // not sure if an fd is the right thing to return here, but it will do for now. /// Returns a file descriptor to use for poll/select on the CFG handle -pub fn fd_get(handle: Handle) -> Result<i32> { +pub fn fd_get(handle: &Handle) -> Result<i32> { let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int; let res = unsafe { ffi::corosync_cfg_fd_get(handle.cfg_handle, c_fd) }; if res == ffi::CS_OK { @@ -147,7 +173,7 @@ pub fn fd_get(handle: Handle) -> Result<i32> { } /// Get the local [NodeId] -pub fn local_get(handle: Handle) -> Result<NodeId> { +pub fn local_get(handle: &Handle) -> Result<NodeId> { let mut nodeid: u32 = 0; let res = unsafe { ffi::corosync_cfg_local_get(handle.cfg_handle, &mut nodeid) }; if res == ffi::CS_OK { @@ -158,7 +184,7 @@ pub fn local_get(handle: Handle) -> Result<NodeId> { } /// Reload the cluster configuration on all nodes -pub fn reload_cnfig(handle: Handle) -> Result<()> { +pub fn reload_cnfig(handle: &Handle) -> Result<()> { let res = unsafe { ffi::corosync_cfg_reload_config(handle.cfg_handle) }; if res == ffi::CS_OK { Ok(()) @@ -168,7 +194,7 @@ pub fn reload_cnfig(handle: Handle) -> Result<()> { } /// Re-open the cluster log files, on this node only -pub fn reopen_log_files(handle: Handle) -> Result<()> { +pub fn reopen_log_files(handle: &Handle) -> Result<()> { let res = unsafe { ffi::corosync_cfg_reopen_log_files(handle.cfg_handle) }; if res == ffi::CS_OK { Ok(()) @@ -179,7 +205,7 @@ pub fn reopen_log_files(handle: Handle) -> Result<()> { /// Tell another cluster node to shutdown. reason is a string that /// will be written to the system log files. -pub fn kill_node(handle: Handle, nodeid: NodeId, reason: &str) -> Result<()> { +pub fn kill_node(handle: &Handle, nodeid: NodeId, reason: &str) -> Result<()> { let c_string = { match CString::new(reason) { Ok(cs) => cs, @@ -200,7 +226,7 @@ pub fn kill_node(handle: Handle, nodeid: NodeId, reason: &str) -> Result<()> { /// Ask this cluster node to shutdown. If [ShutdownFlags] is set to Request then ///it may be refused by other applications /// that have registered for shutdown callbacks. -pub fn try_shutdown(handle: Handle, flags: ShutdownFlags) -> Result<()> { +pub fn try_shutdown(handle: &Handle, flags: ShutdownFlags) -> Result<()> { let c_flags = match flags { ShutdownFlags::Request => 0, ShutdownFlags::Regardless => 1, @@ -215,7 +241,7 @@ pub fn try_shutdown(handle: Handle, flags: ShutdownFlags) -> Result<()> { } /// Reply to a shutdown request with Yes or No [ShutdownReply] -pub fn reply_to_shutdown(handle: Handle, flags: ShutdownReply) -> Result<()> { +pub fn reply_to_shutdown(handle: &Handle, flags: ShutdownReply) -> Result<()> { let c_flags = match flags { ShutdownReply::No => 0, ShutdownReply::Yes => 1, @@ -229,7 +255,7 @@ pub fn reply_to_shutdown(handle: Handle, flags: ShutdownReply) -> Result<()> { } /// Call any/all active CFG callbacks for this [Handle] see [DispatchFlags] for details -pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { +pub fn dispatch(handle: &Handle, flags: DispatchFlags) -> Result<()> { let res = unsafe { ffi::corosync_cfg_dispatch(handle.cfg_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -293,7 +319,7 @@ fn new_ls() -> ffi::corosync_knet_link_status_v1 { /// Get the extended status of a node in the cluster (including active links) from its [NodeId]. /// Returns a filled in [NodeStatus] struct pub fn node_status_get( - handle: Handle, + handle: &Handle, nodeid: NodeId, _version: NodeStatusVersion, ) -> Result<NodeStatus> { @@ -328,7 +354,7 @@ pub fn node_status_get( } /// Start tracking for shutdown notifications -pub fn track_start(handle: Handle, _flags: TrackFlags) -> Result<()> { +pub fn track_start(handle: &Handle, _flags: TrackFlags) -> Result<()> { let res = unsafe { ffi::corosync_cfg_trackstart(handle.cfg_handle, 0) }; if res == ffi::CS_OK { Ok(()) @@ -338,7 +364,7 @@ pub fn track_start(handle: Handle, _flags: TrackFlags) -> Result<()> { } /// Stop tracking for shutdown notifications -pub fn track_stop(handle: Handle) -> Result<()> { +pub fn track_stop(handle: &Handle) -> Result<()> { let res = unsafe { ffi::corosync_cfg_trackstop(handle.cfg_handle) }; if res == ffi::CS_OK { Ok(()) diff --git a/bindings/rust/src/cmap.rs b/bindings/rust/src/cmap.rs index 454fbee2..4f3651aa 100644 --- a/bindings/rust/src/cmap.rs +++ b/bindings/rust/src/cmap.rs @@ -62,10 +62,33 @@ impl fmt::Display for TrackType { } } -#[derive(Copy, Clone)] /// A handle returned from [initialize], needs to be passed to all other cmap API calls pub struct Handle { cmap_handle: u64, + clone: bool, +} + +impl Clone for Handle { + fn clone(&self) -> Handle { + Handle { + cmap_handle: self.cmap_handle, + clone: true, + } + } +} + +impl Drop for Handle { + fn drop(self: &mut Handle) { + if !self.clone { + let _e = finalize(self); + } + } +} +// Clones count as equivalent +impl PartialEq for Handle { + fn eq(&self, other: &Handle) -> bool { + self.cmap_handle == other.cmap_handle + } } #[derive(Copy, Clone)] @@ -97,8 +120,9 @@ pub fn initialize(map: Map) -> Result<Handle> { if res == ffi::CS_OK { let rhandle = Handle { cmap_handle: handle, + clone: false, }; - HANDLE_HASH.lock().unwrap().insert(handle, rhandle); + HANDLE_HASH.lock().unwrap().insert(handle, rhandle.clone()); Ok(rhandle) } else { Err(CsError::from_c(res)) @@ -108,7 +132,7 @@ pub fn initialize(map: Map) -> Result<Handle> { /// Finish with a connection to corosync. /// Takes a [Handle] as returned from [initialize] -pub fn finalize(handle: Handle) -> Result<()> { +pub fn finalize(handle: &Handle) -> Result<()> { let res = unsafe { ffi::cmap_finalize(handle.cmap_handle) }; if res == ffi::CS_OK { HANDLE_HASH.lock().unwrap().remove(&handle.cmap_handle); @@ -121,7 +145,7 @@ pub fn finalize(handle: Handle) -> Result<()> { /// Return a file descriptor to use for poll/select on the CMAP handle. /// Takes a [Handle] as returned from [initialize], /// returns a C file descriptor as i32 -pub fn fd_get(handle: Handle) -> Result<i32> { +pub fn fd_get(handle: &Handle) -> Result<i32> { let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int; let res = unsafe { ffi::cmap_fd_get(handle.cmap_handle, c_fd) }; if res == ffi::CS_OK { @@ -134,7 +158,7 @@ pub fn fd_get(handle: Handle) -> Result<i32> { /// Dispatch any/all active CMAP callbacks. /// Takes a [Handle] as returned from [initialize], /// flags [DispatchFlags] tells it how many items to dispatch before returning -pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { +pub fn dispatch(handle: &Handle, flags: DispatchFlags) -> Result<()> { let res = unsafe { ffi::cmap_dispatch(handle.cmap_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -146,7 +170,7 @@ pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { /// Get the current 'context' value for this handle /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source -pub fn context_get(handle: Handle) -> Result<u64> { +pub fn context_get(handle: &Handle) -> Result<u64> { let (res, context) = unsafe { let mut context: u64 = 0; let c_context: *mut c_void = &mut context as *mut _ as *mut c_void; @@ -164,7 +188,7 @@ pub fn context_get(handle: Handle) -> Result<u64> { /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source. /// Normally this is set in [initialize], but this allows it to be changed -pub fn context_set(handle: Handle, context: u64) -> Result<()> { +pub fn context_set(handle: &Handle, context: u64) -> Result<()> { let res = unsafe { let c_context = context as *mut c_void; ffi::cmap_context_set(handle.cmap_handle, c_context) @@ -274,7 +298,7 @@ fn string_to_cstring_validated(key: &str, maxlen: usize) -> Result<CString> { } fn set_value( - handle: Handle, + handle: &Handle, key_name: &str, datatype: DataType, value: *mut c_void, @@ -333,7 +357,7 @@ fn is_numeric_type(dtype: DataType) -> bool { /// Function to set a generic numeric value /// This doesn't work for strings or binaries -pub fn set_number<T: Copy>(handle: Handle, key_name: &str, value: T) -> Result<()> { +pub fn set_number<T: Copy>(handle: &Handle, key_name: &str, value: T) -> Result<()> { let (c_type, c_size) = generic_to_cmap(value); if is_numeric_type(c_type) { @@ -345,21 +369,21 @@ pub fn set_number<T: Copy>(handle: Handle, key_name: &str, value: T) -> Result<( } } -pub fn set_u8(handle: Handle, key_name: &str, value: u8) -> Result<()> { +pub fn set_u8(handle: &Handle, key_name: &str, value: u8) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::UInt8, c_value as *mut c_void, 1) } /// Sets an i8 value into cmap -pub fn set_i8(handle: Handle, key_name: &str, value: i8) -> Result<()> { +pub fn set_i8(handle: &Handle, key_name: &str, value: i8) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::Int8, c_value as *mut c_void, 1) } /// Sets a u16 value into cmap -pub fn set_u16(handle: Handle, key_name: &str, value: u16) -> Result<()> { +pub fn set_u16(handle: &Handle, key_name: &str, value: u16) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value( @@ -372,28 +396,28 @@ pub fn set_u16(handle: Handle, key_name: &str, value: u16) -> Result<()> { } /// Sets an i16 value into cmap -pub fn set_i16(handle: Handle, key_name: &str, value: i16) -> Result<()> { +pub fn set_i16(handle: &Handle, key_name: &str, value: i16) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::Int16, c_value as *mut c_void, 2) } /// Sets a u32 value into cmap -pub fn set_u32(handle: Handle, key_name: &str, value: u32) -> Result<()> { +pub fn set_u32(handle: &Handle, key_name: &str, value: u32) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::UInt32, c_value, 4) } /// Sets an i32 value into cmap -pub fn set_i132(handle: Handle, key_name: &str, value: i32) -> Result<()> { +pub fn set_i132(handle: &Handle, key_name: &str, value: i32) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::Int32, c_value as *mut c_void, 4) } /// Sets a u64 value into cmap -pub fn set_u64(handle: Handle, key_name: &str, value: u64) -> Result<()> { +pub fn set_u64(handle: &Handle, key_name: &str, value: u64) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value( @@ -406,14 +430,14 @@ pub fn set_u64(handle: Handle, key_name: &str, value: u64) -> Result<()> { } /// Sets an i64 value into cmap -pub fn set_i164(handle: Handle, key_name: &str, value: i64) -> Result<()> { +pub fn set_i164(handle: &Handle, key_name: &str, value: i64) -> Result<()> { let mut tmp = value; let c_value: *mut c_void = &mut tmp as *mut _ as *mut c_void; set_value(handle, key_name, DataType::Int64, c_value as *mut c_void, 8) } /// Sets a string value into cmap -pub fn set_string(handle: Handle, key_name: &str, value: &str) -> Result<()> { +pub fn set_string(handle: &Handle, key_name: &str, value: &str) -> Result<()> { let v_string = string_to_cstring_validated(value, 0)?; set_value( handle, @@ -425,7 +449,7 @@ pub fn set_string(handle: Handle, key_name: &str, value: &str) -> Result<()> { } /// Sets a binary value into cmap -pub fn set_binary(handle: Handle, key_name: &str, value: &[u8]) -> Result<()> { +pub fn set_binary(handle: &Handle, key_name: &str, value: &[u8]) -> Result<()> { set_value( handle, key_name, @@ -436,7 +460,7 @@ pub fn set_binary(handle: Handle, key_name: &str, value: &[u8]) -> Result<()> { } /// Sets a [Data] type into cmap -pub fn set(handle: Handle, key_name: &str, data: &Data) -> Result<()> { +pub fn set(handle: &Handle, key_name: &str, data: &Data) -> Result<()> { let (datatype, datalen, c_value) = match data { Data::Int8(v) => { let mut tmp = *v; @@ -597,7 +621,7 @@ fn c_to_data(value_size: usize, c_key_type: u32, c_value: *const u8) -> Result<D const INITIAL_SIZE: usize = 256; /// Get a value from cmap, returned as a [Data] struct, so could be anything -pub fn get(handle: Handle, key_name: &str) -> Result<Data> { +pub fn get(handle: &Handle, key_name: &str) -> Result<Data> { let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?; let mut value_size: usize = 16; let mut c_key_type: u32 = 0; @@ -638,7 +662,7 @@ pub fn get(handle: Handle, key_name: &str) -> Result<Data> { } /// increment the value in a cmap key (must be a numeric type) -pub fn inc(handle: Handle, key_name: &str) -> Result<()> { +pub fn inc(handle: &Handle, key_name: &str) -> Result<()> { let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?; let res = unsafe { ffi::cmap_inc(handle.cmap_handle, csname.as_ptr()) }; if res == ffi::CS_OK { @@ -649,7 +673,7 @@ pub fn inc(handle: Handle, key_name: &str) -> Result<()> { } /// decrement the value in a cmap key (must be a numeric type) -pub fn dec(handle: Handle, key_name: &str) -> Result<()> { +pub fn dec(handle: &Handle, key_name: &str) -> Result<()> { let csname = string_to_cstring_validated(key_name, CMAP_KEYNAME_MAXLENGTH)?; let res = unsafe { ffi::cmap_dec(handle.cmap_handle, csname.as_ptr()) }; if res == ffi::CS_OK { @@ -721,7 +745,7 @@ pub struct NotifyCallback { /// Track changes in cmap values, multiple [TrackHandle]s per [Handle] are allowed pub fn track_add( - handle: Handle, + handle: &Handle, key_name: &str, track_type: TrackType, notify_callback: &NotifyCallback, @@ -755,7 +779,7 @@ pub fn track_add( } /// Remove a tracker frm this [Handle] -pub fn track_delete(handle: Handle, track_handle: TrackHandle) -> Result<()> { +pub fn track_delete(handle: &Handle, track_handle: TrackHandle) -> Result<()> { let res = unsafe { ffi::cmap_track_delete(handle.cmap_handle, track_handle.track_handle) }; if res == ffi::CS_OK { TRACKHANDLE_HASH @@ -864,7 +888,7 @@ impl Iterator for CmapIntoIter { impl CmapIterStart { /// Create a new [CmapIterStart] object for iterating over a list of cmap keys - pub fn new(cmap_handle: Handle, prefix: &str) -> Result<CmapIterStart> { + pub fn new(cmap_handle: &Handle, prefix: &str) -> Result<CmapIterStart> { let mut iter_handle: u64 = 0; let res = unsafe { let c_prefix = string_to_cstring_validated(prefix, CMAP_KEYNAME_MAXLENGTH)?; diff --git a/bindings/rust/src/cpg.rs b/bindings/rust/src/cpg.rs index 12464975..36346453 100644 --- a/bindings/rust/src/cpg.rs +++ b/bindings/rust/src/cpg.rs @@ -160,10 +160,35 @@ pub enum ModelData { } /// A handle into the cpg library. Returned from [initialize] and needed for all other calls -#[derive(Copy, Clone)] pub struct Handle { cpg_handle: u64, // Corosync library handle model_data: ModelData, + clone: bool, +} + +impl Clone for Handle { + fn clone(&self) -> Handle { + Handle { + cpg_handle: self.cpg_handle, + model_data: self.model_data, + clone: true, + } + } +} + +impl Drop for Handle { + fn drop(self: &mut Handle) { + if !self.clone { + let _e = finalize(self); + } + } +} + +// Clones count as equivalent +impl PartialEq for Handle { + fn eq(&self, other: &Handle) -> bool { + self.cpg_handle == other.cpg_handle + } } // Used to convert a CPG handle into one of ours @@ -329,8 +354,9 @@ pub fn initialize(model_data: &ModelData, context: u64) -> Result<Handle> { let rhandle = Handle { cpg_handle: handle, model_data: *model_data, + clone: false, }; - HANDLE_HASH.lock().unwrap().insert(handle, rhandle); + HANDLE_HASH.lock().unwrap().insert(handle, rhandle.clone()); Ok(rhandle) } else { Err(CsError::from_c(res)) @@ -339,7 +365,7 @@ pub fn initialize(model_data: &ModelData, context: u64) -> Result<Handle> { } /// Finish with a connection to corosync -pub fn finalize(handle: Handle) -> Result<()> { +pub fn finalize(handle: &Handle) -> Result<()> { let res = unsafe { ffi::cpg_finalize(handle.cpg_handle) }; if res == ffi::CS_OK { HANDLE_HASH.lock().unwrap().remove(&handle.cpg_handle); @@ -351,7 +377,7 @@ pub fn finalize(handle: Handle) -> Result<()> { // Not sure if an FD is the right thing to return here, but it will do for now. /// Returns a file descriptor to use for poll/select on the CPG handle -pub fn fd_get(handle: Handle) -> Result<i32> { +pub fn fd_get(handle: &Handle) -> Result<i32> { let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int; let res = unsafe { ffi::cpg_fd_get(handle.cpg_handle, c_fd) }; if res == ffi::CS_OK { @@ -362,7 +388,7 @@ pub fn fd_get(handle: Handle) -> Result<i32> { } /// Call any/all active CPG callbacks for this [Handle] see [DispatchFlags] for details -pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { +pub fn dispatch(handle: &Handle, flags: DispatchFlags) -> Result<()> { let res = unsafe { ffi::cpg_dispatch(handle.cpg_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -372,7 +398,7 @@ pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { } /// Joins a CPG group for sending and receiving messages -pub fn join(handle: Handle, group: &str) -> Result<()> { +pub fn join(handle: &Handle, group: &str) -> Result<()> { let res = unsafe { let c_group = string_to_cpg_name(group)?; ffi::cpg_join(handle.cpg_handle, &c_group) @@ -386,7 +412,7 @@ pub fn join(handle: Handle, group: &str) -> Result<()> { /// Leave the currently joined CPG group, another group can now be joined on /// the same [Handle] or [finalize] can be called to finish using CPG -pub fn leave(handle: Handle, group: &str) -> Result<()> { +pub fn leave(handle: &Handle, group: &str) -> Result<()> { let res = unsafe { let c_group = string_to_cpg_name(group)?; ffi::cpg_leave(handle.cpg_handle, &c_group) @@ -399,7 +425,7 @@ pub fn leave(handle: Handle, group: &str) -> Result<()> { } /// Get the local node ID -pub fn local_get(handle: Handle) -> Result<NodeId> { +pub fn local_get(handle: &Handle) -> Result<NodeId> { let mut nodeid: u32 = 0; let res = unsafe { ffi::cpg_local_get(handle.cpg_handle, &mut nodeid) }; if res == ffi::CS_OK { @@ -410,7 +436,7 @@ pub fn local_get(handle: Handle) -> Result<NodeId> { } /// Get a list of members of a CPG group as a vector of [Address] structs -pub fn membership_get(handle: Handle, group: &str) -> Result<Vec<Address>> { +pub fn membership_get(handle: &Handle, group: &str) -> Result<Vec<Address>> { let mut member_list_entries: i32 = 0; let member_list = [ffi::cpg_address { nodeid: 0, @@ -440,7 +466,7 @@ pub fn membership_get(handle: Handle, group: &str) -> Result<Vec<Address>> { /// Get the maximum size that CPG can send in one corosync message, /// any messages sent via [mcast_joined] that are larger than this /// will be fragmented -pub fn max_atomic_msgsize_get(handle: Handle) -> Result<u32> { +pub fn max_atomic_msgsize_get(handle: &Handle) -> Result<u32> { let mut asize: u32 = 0; let res = unsafe { ffi::cpg_max_atomic_msgsize_get(handle.cpg_handle, &mut asize) }; if res == ffi::CS_OK { @@ -453,7 +479,7 @@ pub fn max_atomic_msgsize_get(handle: Handle) -> Result<u32> { /// Get the current 'context' value for this handle. /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source -pub fn context_get(handle: Handle) -> Result<u64> { +pub fn context_get(handle: &Handle) -> Result<u64> { let mut c_context: *mut c_void = &mut 0u64 as *mut _ as *mut c_void; let (res, context) = unsafe { let r = ffi::cpg_context_get(handle.cpg_handle, &mut c_context); @@ -471,7 +497,7 @@ pub fn context_get(handle: Handle) -> Result<u64> { /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source. /// Normally this is set in [initialize], but this allows it to be changed -pub fn context_set(handle: Handle, context: u64) -> Result<()> { +pub fn context_set(handle: &Handle, context: u64) -> Result<()> { let res = unsafe { let c_context = context as *mut c_void; ffi::cpg_context_set(handle.cpg_handle, c_context) @@ -484,7 +510,7 @@ pub fn context_set(handle: Handle, context: u64) -> Result<()> { } /// Get the flow control state of corosync CPG -pub fn flow_control_state_get(handle: Handle) -> Result<bool> { +pub fn flow_control_state_get(handle: &Handle) -> Result<bool> { let mut fc_state: u32 = 0; let res = unsafe { ffi::cpg_flow_control_state_get(handle.cpg_handle, &mut fc_state) }; if res == ffi::CS_OK { @@ -499,7 +525,7 @@ pub fn flow_control_state_get(handle: Handle) -> Result<bool> { } /// Send a message to the currently joined CPG group -pub fn mcast_joined(handle: Handle, guarantee: Guarantee, msg: &[u8]) -> Result<()> { +pub fn mcast_joined(handle: &Handle, guarantee: Guarantee, msg: &[u8]) -> Result<()> { let c_iovec = ffi::iovec { iov_base: msg.as_ptr() as *mut c_void, iov_len: msg.len(), @@ -589,7 +615,7 @@ impl Iterator for CpgIntoIter { impl CpgIterStart { /// Create a new [CpgIterStart] object for iterating over a list of active CPG groups - pub fn new(cpg_handle: Handle, group: &str, iter_type: CpgIterType) -> Result<CpgIterStart> { + pub fn new(cpg_handle: &Handle, group: &str, iter_type: CpgIterType) -> Result<CpgIterStart> { let mut iter_handle: u64 = 0; let res = unsafe { let mut c_group = string_to_cpg_name(group)?; diff --git a/bindings/rust/src/quorum.rs b/bindings/rust/src/quorum.rs index 25c2fe62..d20f1d64 100644 --- a/bindings/rust/src/quorum.rs +++ b/bindings/rust/src/quorum.rs @@ -137,10 +137,35 @@ pub struct Model1Data { } /// A handle into the quorum library. Returned from [initialize] and needed for all other calls -#[derive(Copy, Clone)] pub struct Handle { quorum_handle: u64, model_data: ModelData, + clone: bool, +} + +impl Clone for Handle { + fn clone(&self) -> Handle { + Handle { + quorum_handle: self.quorum_handle, + model_data: self.model_data, + clone: true, + } + } +} + +impl Drop for Handle { + fn drop(self: &mut Handle) { + if !self.clone { + let _e = finalize(self); + } + } +} + +// Clones count as equivalent +impl PartialEq for Handle { + fn eq(&self, other: &Handle) -> bool { + self.quorum_handle == other.quorum_handle + } } /// Initialize a connection to the quorum library. You must call this before doing anything @@ -187,13 +212,14 @@ pub fn initialize(model_data: &ModelData, context: u64) -> Result<(Handle, Quoru let rhandle = Handle { quorum_handle: handle, model_data: *model_data, + clone: false, }; - HANDLE_HASH.lock().unwrap().insert(handle, rhandle); + HANDLE_HASH.lock().unwrap().insert(handle, rhandle.clone()); Ok((rhandle, quorum_type)) } /// Finish with a connection to corosync -pub fn finalize(handle: Handle) -> Result<()> { +pub fn finalize(handle: &Handle) -> Result<()> { let res = unsafe { ffi::quorum_finalize(handle.quorum_handle) }; if res == ffi::CS_OK { HANDLE_HASH.lock().unwrap().remove(&handle.quorum_handle); @@ -205,7 +231,7 @@ pub fn finalize(handle: Handle) -> Result<()> { // Not sure if an FD is the right thing to return here, but it will do for now. /// Return a file descriptor to use for poll/select on the QUORUM handle -pub fn fd_get(handle: Handle) -> Result<i32> { +pub fn fd_get(handle: &Handle) -> Result<i32> { let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int; let res = unsafe { ffi::quorum_fd_get(handle.quorum_handle, c_fd) }; if res == ffi::CS_OK { @@ -216,7 +242,7 @@ pub fn fd_get(handle: Handle) -> Result<i32> { } /// Display any/all active QUORUM callbacks for this [Handle], see [DispatchFlags] for details -pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { +pub fn dispatch(handle: &Handle, flags: DispatchFlags) -> Result<()> { let res = unsafe { ffi::quorum_dispatch(handle.quorum_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -226,7 +252,7 @@ pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { } /// Return the quorate status of the cluster -pub fn getquorate(handle: Handle) -> Result<bool> { +pub fn getquorate(handle: &Handle) -> Result<bool> { let c_quorate: *mut c_int = &mut 0 as *mut _ as *mut c_int; let (res, r_quorate) = unsafe { let res = ffi::quorum_getquorate(handle.quorum_handle, c_quorate); @@ -245,7 +271,7 @@ pub fn getquorate(handle: Handle) -> Result<bool> { } /// Track node and quorum changes -pub fn trackstart(handle: Handle, flags: TrackFlags) -> Result<()> { +pub fn trackstart(handle: &Handle, flags: TrackFlags) -> Result<()> { let res = unsafe { ffi::quorum_trackstart(handle.quorum_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -255,7 +281,7 @@ pub fn trackstart(handle: Handle, flags: TrackFlags) -> Result<()> { } /// Stop tracking node and quorum changes -pub fn trackstop(handle: Handle) -> Result<()> { +pub fn trackstop(handle: &Handle) -> Result<()> { let res = unsafe { ffi::quorum_trackstop(handle.quorum_handle) }; if res == ffi::CS_OK { Ok(()) @@ -267,7 +293,7 @@ pub fn trackstop(handle: Handle) -> Result<()> { /// Get the current 'context' value for this handle. /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source -pub fn context_get(handle: Handle) -> Result<u64> { +pub fn context_get(handle: &Handle) -> Result<u64> { let (res, context) = unsafe { let mut context: u64 = 0; let c_context: *mut c_void = &mut context as *mut _ as *mut c_void; @@ -285,7 +311,7 @@ pub fn context_get(handle: Handle) -> Result<u64> { /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source. /// Normally this is set in [initialize], but this allows it to be changed -pub fn context_set(handle: Handle, context: u64) -> Result<()> { +pub fn context_set(handle: &Handle, context: u64) -> Result<()> { let res = unsafe { let c_context = context as *mut c_void; ffi::quorum_context_set(handle.quorum_handle, c_context) diff --git a/bindings/rust/src/votequorum.rs b/bindings/rust/src/votequorum.rs index 4718b586..1e34fcac 100644 --- a/bindings/rust/src/votequorum.rs +++ b/bindings/rust/src/votequorum.rs @@ -189,10 +189,35 @@ pub struct Callbacks { } /// A handle into the votequorum library. Returned from [initialize] and needed for all other calls -#[derive(Copy, Clone)] pub struct Handle { votequorum_handle: u64, callbacks: Callbacks, + clone: bool, +} + +impl Clone for Handle { + fn clone(&self) -> Handle { + Handle { + votequorum_handle: self.votequorum_handle, + callbacks: self.callbacks, + clone: true, + } + } +} + +impl Drop for Handle { + fn drop(self: &mut Handle) { + if !self.clone { + let _e = finalize(self); + } + } +} + +// Clones count as equivalent +impl PartialEq for Handle { + fn eq(&self, other: &Handle) -> bool { + self.votequorum_handle == other.votequorum_handle + } } /// Initialize a connection to the votequorum library. You must call this before doing anything @@ -213,8 +238,9 @@ pub fn initialize(callbacks: &Callbacks) -> Result<Handle> { let rhandle = Handle { votequorum_handle: handle, callbacks: *callbacks, + clone: false, }; - HANDLE_HASH.lock().unwrap().insert(handle, rhandle); + HANDLE_HASH.lock().unwrap().insert(handle, rhandle.clone()); Ok(rhandle) } else { Err(CsError::from_c(res)) @@ -223,7 +249,7 @@ pub fn initialize(callbacks: &Callbacks) -> Result<Handle> { } /// Finish with a connection to corosync -pub fn finalize(handle: Handle) -> Result<()> { +pub fn finalize(handle: &Handle) -> Result<()> { let res = unsafe { ffi::votequorum_finalize(handle.votequorum_handle) }; if res == ffi::CS_OK { HANDLE_HASH @@ -238,7 +264,7 @@ pub fn finalize(handle: Handle) -> Result<()> { // Not sure if an FD is the right thing to return here, but it will do for now. /// Return a file descriptor to use for poll/select on the VOTEQUORUM handle -pub fn fd_get(handle: Handle) -> Result<i32> { +pub fn fd_get(handle: &Handle) -> Result<i32> { let c_fd: *mut c_int = &mut 0 as *mut _ as *mut c_int; let res = unsafe { ffi::votequorum_fd_get(handle.votequorum_handle, c_fd) }; if res == ffi::CS_OK { @@ -251,7 +277,7 @@ pub fn fd_get(handle: Handle) -> Result<i32> { const VOTEQUORUM_QDEVICE_MAX_NAME_LEN: usize = 255; /// Returns detailed information about a node in a [NodeInfo] structure -pub fn get_info(handle: Handle, nodeid: NodeId) -> Result<NodeInfo> { +pub fn get_info(handle: &Handle, nodeid: NodeId) -> Result<NodeInfo> { let mut c_info = ffi::votequorum_info { node_id: 0, node_state: 0, @@ -293,7 +319,7 @@ pub fn get_info(handle: Handle, nodeid: NodeId) -> Result<NodeInfo> { } /// Call any/all active votequorum callbacks for this [Handle]. see [DispatchFlags] for details -pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { +pub fn dispatch(handle: &Handle, flags: DispatchFlags) -> Result<()> { let res = unsafe { ffi::votequorum_dispatch(handle.votequorum_handle, flags as u32) }; if res == ffi::CS_OK { Ok(()) @@ -303,7 +329,7 @@ pub fn dispatch(handle: Handle, flags: DispatchFlags) -> Result<()> { } /// Track node and votequorum changes -pub fn trackstart(handle: Handle, context: u64, flags: TrackFlags) -> Result<()> { +pub fn trackstart(handle: &Handle, context: u64, flags: TrackFlags) -> Result<()> { let res = unsafe { ffi::votequorum_trackstart(handle.votequorum_handle, context, flags as u32) }; if res == ffi::CS_OK { @@ -314,7 +340,7 @@ pub fn trackstart(handle: Handle, context: u64, flags: TrackFlags) -> Result<()> } /// Stop tracking node and votequorum changes -pub fn trackstop(handle: Handle) -> Result<()> { +pub fn trackstop(handle: &Handle) -> Result<()> { let res = unsafe { ffi::votequorum_trackstop(handle.votequorum_handle) }; if res == ffi::CS_OK { Ok(()) @@ -326,7 +352,7 @@ pub fn trackstop(handle: Handle) -> Result<()> { /// Get the current 'context' value for this handle. /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source -pub fn context_get(handle: Handle) -> Result<u64> { +pub fn context_get(handle: &Handle) -> Result<u64> { let (res, context) = unsafe { let mut c_context: *mut c_void = &mut 0u64 as *mut _ as *mut c_void; let r = ffi::votequorum_context_get(handle.votequorum_handle, &mut c_context); @@ -344,7 +370,7 @@ pub fn context_get(handle: Handle) -> Result<u64> { /// The context value is an arbitrary value that is always passed /// back to callbacks to help identify the source. /// Normally this is set in [trackstart], but this allows it to be changed -pub fn context_set(handle: Handle, context: u64) -> Result<()> { +pub fn context_set(handle: &Handle, context: u64) -> Result<()> { let res = unsafe { let c_context = context as *mut c_void; ffi::votequorum_context_set(handle.votequorum_handle, c_context) @@ -358,7 +384,7 @@ pub fn context_set(handle: Handle, context: u64) -> Result<()> { /// Set the current expected_votes for the cluster, this value must /// be valid and not result in an inquorate cluster. -pub fn set_expected(handle: Handle, expected_votes: u32) -> Result<()> { +pub fn set_expected(handle: &Handle, expected_votes: u32) -> Result<()> { let res = unsafe { ffi::votequorum_setexpected(handle.votequorum_handle, expected_votes) }; if res == ffi::CS_OK { Ok(()) @@ -368,7 +394,7 @@ pub fn set_expected(handle: Handle, expected_votes: u32) -> Result<()> { } /// Set the current votes for a node -pub fn set_votes(handle: Handle, nodeid: NodeId, votes: u32) -> Result<()> { +pub fn set_votes(handle: &Handle, nodeid: NodeId, votes: u32) -> Result<()> { let res = unsafe { ffi::votequorum_setvotes(handle.votequorum_handle, u32::from(nodeid), votes) }; if res == ffi::CS_OK { @@ -379,7 +405,7 @@ pub fn set_votes(handle: Handle, nodeid: NodeId, votes: u32) -> Result<()> { } /// Register a quorum device -pub fn qdevice_register(handle: Handle, name: &str) -> Result<()> { +pub fn qdevice_register(handle: &Handle, name: &str) -> Result<()> { let c_string = { match CString::new(name) { Ok(cs) => cs, @@ -397,7 +423,7 @@ pub fn qdevice_register(handle: Handle, name: &str) -> Result<()> { } /// Unregister a quorum device -pub fn qdevice_unregister(handle: Handle, name: &str) -> Result<()> { +pub fn qdevice_unregister(handle: &Handle, name: &str) -> Result<()> { let c_string = { match CString::new(name) { Ok(cs) => cs, @@ -415,7 +441,7 @@ pub fn qdevice_unregister(handle: Handle, name: &str) -> Result<()> { } /// Update the name of a quorum device -pub fn qdevice_update(handle: Handle, oldname: &str, newname: &str) -> Result<()> { +pub fn qdevice_update(handle: &Handle, oldname: &str, newname: &str) -> Result<()> { let on_string = { match CString::new(oldname) { Ok(cs) => cs, @@ -446,7 +472,7 @@ pub fn qdevice_update(handle: Handle, oldname: &str, newname: &str) -> Result<() /// Poll a quorum device /// This must be done more often than the qdevice timeout (default 10s) while the device is active /// and the [RingId] must match the current value returned from the callbacks for it to be accepted. -pub fn qdevice_poll(handle: Handle, name: &str, cast_vote: bool, ring_id: &RingId) -> Result<()> { +pub fn qdevice_poll(handle: &Handle, name: &str, cast_vote: bool, ring_id: &RingId) -> Result<()> { let c_string = { match CString::new(name) { Ok(cs) => cs, @@ -476,7 +502,7 @@ pub fn qdevice_poll(handle: Handle, name: &str, cast_vote: bool, ring_id: &RingI } /// Allow qdevice to tell votequorum if master_wins can be enabled or not -pub fn qdevice_master_wins(handle: Handle, name: &str, master_wins: bool) -> Result<()> { +pub fn qdevice_master_wins(handle: &Handle, name: &str, master_wins: bool) -> Result<()> { let c_string = { match CString::new(name) { Ok(cs) => cs, diff --git a/bindings/rust/tests/src/bin/cfg-test.rs b/bindings/rust/tests/src/bin/cfg-test.rs index cd70d388..1b245251 100644 --- a/bindings/rust/tests/src/bin/cfg-test.rs +++ b/bindings/rust/tests/src/bin/cfg-test.rs @@ -5,7 +5,7 @@ use corosync::{cfg, NodeId}; use std::thread::spawn; -fn dispatch_thread(handle: cfg::Handle) { +fn dispatch_thread(handle: &cfg::Handle) { loop { if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() { return; @@ -18,7 +18,7 @@ fn shutdown_check_fn(handle: &cfg::Handle, _flags: u32) { println!("in shutdown callback"); // DON'T shutdown corosync - we're just testing - if let Err(e) = cfg::reply_to_shutdown(*handle, cfg::ShutdownReply::No) { + if let Err(e) = cfg::reply_to_shutdown(handle, cfg::ShutdownReply::No) { println!("Error in CFG replyto_shutdown: {e}"); } } @@ -52,10 +52,10 @@ fn main() { } }; - match cfg::track_start(handle2, cfg::TrackFlags::None) { + match cfg::track_start(&handle2, cfg::TrackFlags::None) { Ok(_) => { // Run handle2 dispatch in its own thread - spawn(move || dispatch_thread(handle2)); + spawn(move || dispatch_thread(&handle2)); } Err(e) => { println!("Error in CFG track_start: {e}"); @@ -63,7 +63,7 @@ fn main() { }; let local_nodeid = { - match cfg::local_get(handle) { + match cfg::local_get(&handle) { Ok(n) => { println!("Local nodeid is {n}"); Some(n) @@ -82,10 +82,10 @@ fn main() { if let Some(our_nodeid) = local_nodeid { let us_plus1 = NodeId::from(u32::from(our_nodeid) + 1); let us_less1 = NodeId::from(u32::from(our_nodeid) - 1); - let mut res = cfg::node_status_get(handle, us_plus1, cfg::NodeStatusVersion::V1); + let mut res = cfg::node_status_get(&handle, us_plus1, cfg::NodeStatusVersion::V1); if let Err(e) = res { println!("Error from node_status_get on nodeid {us_plus1}: {e}"); - res = cfg::node_status_get(handle, us_less1, cfg::NodeStatusVersion::V1); + res = cfg::node_status_get(&handle, us_less1, cfg::NodeStatusVersion::V1); }; match res { Ok(ns) => { @@ -113,8 +113,8 @@ fn main() { } } - // This should not shutdown corosync because the callback on handle2 will refuse it. - match cfg::try_shutdown(handle, cfg::ShutdownFlags::Request) { + // This should not shutdown corosync because the callback on &handle2 will refuse it. + match cfg::try_shutdown(&handle, cfg::ShutdownFlags::Request) { Ok(_) => { println!("CFG try_shutdown suceeded, should return busy"); } @@ -127,7 +127,7 @@ fn main() { // Wait for events loop { - if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() { + if cfg::dispatch(&handle, corosync::DispatchFlags::One).is_err() { break; } } diff --git a/bindings/rust/tests/src/bin/cmap-test.rs b/bindings/rust/tests/src/bin/cmap-test.rs index f4356536..25ec722a 100644 --- a/bindings/rust/tests/src/bin/cmap-test.rs +++ b/bindings/rust/tests/src/bin/cmap-test.rs @@ -31,47 +31,47 @@ fn main() { }; // Test some SETs - if let Err(e) = cmap::set_u32(handle, "test.test_uint32", 456) { + if let Err(e) = cmap::set_u32(&handle, "test.test_uint32", 456) { println!("Error in CMAP set_u32: {e}"); return; }; - if let Err(e) = cmap::set_i16(handle, "test.test_int16", -789) { + if let Err(e) = cmap::set_i16(&handle, "test.test_int16", -789) { println!("Error in CMAP set_i16: {e}"); return; }; - if let Err(e) = cmap::set_number(handle, "test.test_num_1", 6809u32) { + if let Err(e) = cmap::set_number(&handle, "test.test_num_1", 6809u32) { println!("Error in CMAP set_number(u32): {e}"); return; }; // NOT PI (just to avoid clippy whingeing) - if let Err(e) = cmap::set_number(handle, "test.test_num_2", 3.24159265) { + if let Err(e) = cmap::set_number(&handle, "test.test_num_2", 3.24159265) { println!("Error in CMAP set_number(f32): {e}"); return; }; - if let Err(e) = cmap::set_string(handle, "test.test_string", "Hello from Rust") { + if let Err(e) = cmap::set_string(&handle, "test.test_string", "Hello from Rust") { println!("Error in CMAP set_string: {e}"); return; }; let test_d = cmap::Data::UInt64(0xdeadbeefbacecafe); - if let Err(e) = cmap::set(handle, "test.test_data", &test_d) { + if let Err(e) = cmap::set(&handle, "test.test_data", &test_d) { println!("Error in CMAP set_data: {e}"); return; }; // let test_d2 = cmap::Data::UInt32(6809); let test_d2 = cmap::Data::String("Test string in data 12345".to_string()); - if let Err(e) = cmap::set(handle, "test.test_again", &test_d2) { + if let Err(e) = cmap::set(&handle, "test.test_again", &test_d2) { println!("Error in CMAP set_data2: {e}"); return; }; // get them back again - match cmap::get(handle, "test.test_uint32") { + match cmap::get(&handle, "test.test_uint32") { Ok(v) => { println!("GOT uint32 {v}"); } @@ -81,7 +81,7 @@ fn main() { return; } }; - match cmap::get(handle, "test.test_int16") { + match cmap::get(&handle, "test.test_int16") { Ok(v) => { println!("GOT uint16 {v}"); } @@ -92,7 +92,7 @@ fn main() { } }; - match cmap::get(handle, "test.test_num_1") { + match cmap::get(&handle, "test.test_num_1") { Ok(v) => { println!("GOT num {v}"); } @@ -102,7 +102,7 @@ fn main() { return; } }; - match cmap::get(handle, "test.test_num_2") { + match cmap::get(&handle, "test.test_num_2") { Ok(v) => { println!("GOT num {v}"); } @@ -112,7 +112,7 @@ fn main() { return; } }; - match cmap::get(handle, "test.test_string") { + match cmap::get(&handle, "test.test_string") { Ok(v) => { println!("GOT string {v}"); } @@ -123,7 +123,7 @@ fn main() { } }; - match cmap::get(handle, "test.test_data") { + match cmap::get(&handle, "test.test_data") { Ok(v) => match v { cmap::Data::UInt64(u) => println!("GOT data value {u:x}"), _ => println!("ERROR type was not UInt64, got {v}"), @@ -136,7 +136,7 @@ fn main() { }; // Test an iterator - match cmap::CmapIterStart::new(handle, "totem.") { + match cmap::CmapIterStart::new(&handle, "totem.") { Ok(cmap_iter) => { for i in cmap_iter { println!("ITER: {i:?}"); @@ -149,7 +149,7 @@ fn main() { } // Close this handle - if let Err(e) = cmap::finalize(handle) { + if let Err(e) = cmap::finalize(&handle) { println!("Error in CMAP get: {e}"); return; }; @@ -167,7 +167,7 @@ fn main() { notify_fn: Some(track_notify_fn), }; let _track_handle = match cmap::track_add( - handle, + &handle, "stats.srp.memb_merge_detect_tx", cmap::TrackType::MODIFY | cmap::TrackType::ADD | cmap::TrackType::DELETE, &cb, @@ -183,7 +183,7 @@ fn main() { // Wait for events let mut event_num = 0; loop { - if let Err(e) = cmap::dispatch(handle, corosync::DispatchFlags::One) { + if let Err(e) = cmap::dispatch(&handle, corosync::DispatchFlags::One) { println!("Error from CMAP dispatch: {e}"); } // Just do 5 diff --git a/bindings/rust/tests/src/bin/cpg-test.rs b/bindings/rust/tests/src/bin/cpg-test.rs index df83c2d5..c5a58edc 100644 --- a/bindings/rust/tests/src/bin/cpg-test.rs +++ b/bindings/rust/tests/src/bin/cpg-test.rs @@ -66,12 +66,12 @@ fn main() { } }; - if let Err(e) = cpg::join(handle, "TEST") { + if let Err(e) = cpg::join(&handle, "TEST") { println!("Error in CPG join: {e}"); return; } - match cpg::local_get(handle) { + match cpg::local_get(&handle) { Ok(n) => { println!("Local nodeid is {n}"); } @@ -81,7 +81,7 @@ fn main() { } // Test membership_get() - match cpg::membership_get(handle, "TEST") { + match cpg::membership_get(&handle, "TEST") { Ok(m) => { println!(" members: {m:?}"); println!(); @@ -93,13 +93,13 @@ fn main() { // Test context APIs let set_context: u64 = 0xabcdbeefcafe; - if let Err(e) = cpg::context_set(handle, set_context) { + if let Err(e) = cpg::context_set(&handle, set_context) { println!("Error in CPG context_set: {e}"); return; } // NOTE This will fail on 32 bit systems because void* is not u64 - match cpg::context_get(handle) { + match cpg::context_get(&handle) { Ok(c) => { if c != set_context { println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); @@ -111,7 +111,7 @@ fn main() { } // Test iterator - match cpg::CpgIterStart::new(handle, "", cpg::CpgIterType::All) { + match cpg::CpgIterStart::new(&handle, "", cpg::CpgIterType::All) { Ok(cpg_iter) => { for i in cpg_iter { println!("ITER: {i:?}"); @@ -125,7 +125,7 @@ fn main() { // We should receive our own message (at least) in the event loop if let Err(e) = cpg::mcast_joined( - handle, + &handle, cpg::Guarantee::TypeAgreed, &"This is a test".to_string().into_bytes(), ) { @@ -134,7 +134,7 @@ fn main() { // Wait for events loop { - if cpg::dispatch(handle, corosync::DispatchFlags::One).is_err() { + if cpg::dispatch(&handle, corosync::DispatchFlags::One).is_err() { break; } } diff --git a/bindings/rust/tests/src/bin/quorum-test.rs b/bindings/rust/tests/src/bin/quorum-test.rs index 5797b7d0..9436b392 100644 --- a/bindings/rust/tests/src/bin/quorum-test.rs +++ b/bindings/rust/tests/src/bin/quorum-test.rs @@ -51,13 +51,13 @@ fn main() { // Test context APIs let set_context: u64 = 0xabcdbeefcafe; - if let Err(e) = quorum::context_set(handle, set_context) { + if let Err(e) = quorum::context_set(&handle, set_context) { println!("Error in QUORUM context_set: {e}"); return; } // NOTE This will fail on 32 bit systems because void* is not u64 - match quorum::context_get(handle) { + match quorum::context_get(&handle) { Ok(c) => { if c != set_context { println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); @@ -68,14 +68,14 @@ fn main() { } } - if let Err(e) = quorum::trackstart(handle, corosync::TrackFlags::Changes) { + if let Err(e) = quorum::trackstart(&handle, corosync::TrackFlags::Changes) { println!("Error in QUORUM trackstart: {e}"); return; } // Wait for events loop { - if quorum::dispatch(handle, corosync::DispatchFlags::One).is_err() { + if quorum::dispatch(&handle, corosync::DispatchFlags::One).is_err() { break; } } diff --git a/bindings/rust/tests/src/bin/votequorum-test.rs b/bindings/rust/tests/src/bin/votequorum-test.rs index cf9746b6..eebc9f0d 100644 --- a/bindings/rust/tests/src/bin/votequorum-test.rs +++ b/bindings/rust/tests/src/bin/votequorum-test.rs @@ -51,12 +51,12 @@ fn main() { // Test context APIs let set_context: u64 = 0xabcdbeefcafe; - if let Err(e) = votequorum::context_set(handle, set_context) { + if let Err(e) = votequorum::context_set(&handle, set_context) { println!("Error in VOTEQUORUM context_set: {e}"); } // NOTE This will fail on 32 bit systems because void* is not u64 - match votequorum::context_get(handle) { + match votequorum::context_get(&handle) { Ok(c) => { if c != set_context { println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); @@ -69,11 +69,11 @@ fn main() { const QDEVICE_NAME: &str = "RustQdevice"; - if let Err(e) = votequorum::qdevice_register(handle, QDEVICE_NAME) { + if let Err(e) = votequorum::qdevice_register(&handle, QDEVICE_NAME) { println!("Error in VOTEQUORUM qdevice_register: {e}"); } - match votequorum::get_info(handle, corosync::NodeId::from(1u32)) { + match votequorum::get_info(&handle, corosync::NodeId::from(1u32)) { Ok(i) => { println!("Node info for nodeid 1"); println!(" nodeid: {}", i.node_id); @@ -98,18 +98,18 @@ fn main() { } } - if let Err(e) = votequorum::qdevice_unregister(handle, QDEVICE_NAME) { + if let Err(e) = votequorum::qdevice_unregister(&handle, QDEVICE_NAME) { println!("Error in VOTEQUORUM qdevice_unregister: {e}"); } - if let Err(e) = votequorum::trackstart(handle, 99_u64, corosync::TrackFlags::Changes) { + if let Err(e) = votequorum::trackstart(&handle, 99_u64, corosync::TrackFlags::Changes) { println!("Error in VOTEQUORUM trackstart: {e}"); return; } // Wait for events loop { - if votequorum::dispatch(handle, corosync::DispatchFlags::One).is_err() { + if votequorum::dispatch(&handle, corosync::DispatchFlags::One).is_err() { break; } } -- 2.25.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2