Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain id init #223

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e9393d
add time.rs to src as well as to lib.rs (#121)
DS3a Jun 14, 2022
efe7010
added the Time struct
DS3a Jun 14, 2022
f024ad6
add duration.rs to lib and src
DS3a Jun 14, 2022
92e55a1
added the Duration struct
DS3a Jun 14, 2022
c332adb
complete duration.rs
DS3a Jun 15, 2022
68d6df6
add function to return Duration object
DS3a Jun 15, 2022
7eceafe
implemented clone for Duration
DS3a Jun 15, 2022
9c29dee
changes made to time.rs and lib.rs
DS3a Jun 15, 2022
dc66c3c
Merge branch 'ros2-rust:main' into main
DS3a Jun 15, 2022
7f9a6a7
implement Add for time.rs
DS3a Jun 15, 2022
15c9914
add max implementation for Duration
DS3a Jun 15, 2022
49fe3ed
complete time.rs
DS3a Jun 15, 2022
607a201
add clock.rs to src and lib.rs
DS3a Jun 15, 2022
a0d288b
adjusted duration.rs to accomodate negative values as well
DS3a Jun 15, 2022
4260124
refactor time.rs
DS3a Jun 16, 2022
bd356cb
add initial functionality to clock.rs
DS3a Jun 16, 2022
0fce763
add todos to finish after review
DS3a Jun 16, 2022
48a5543
made get_lock publich
DS3a Jun 16, 2022
7853af4
added now to clock.rs
DS3a Jun 16, 2022
c432746
refined duration.rs
DS3a Jun 17, 2022
3a9d90c
implement ord and eq for Tie
DS3a Jun 17, 2022
e5c194d
added some more functions
DS3a Jun 17, 2022
6920fda
Merge branch 'ros2-rust:main' into main
DS3a Jun 23, 2022
4dc0d00
adding ContextBuildr
DS3a Jun 26, 2022
c35dbfd
Merge branch 'ros2-rust:main' into main
DS3a Jul 10, 2022
dc17ed9
Merge branch 'main' of github.com:DS3a/ros2_rust into domain_id_init
DS3a Jul 10, 2022
7adb4f6
implemented new in context/builder.rs
DS3a Jul 10, 2022
3f0360f
add context builder (#206)
DS3a Jul 10, 2022
2f69b60
remove unwanted dependencies
DS3a Jul 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 6 additions & 47 deletions rclrs/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
mod builder;

use crate::rcl_bindings::*;
use crate::{RclrsError, ToResult};
use crate::RclrsError;

use std::ffi::CString;
use std::os::raw::c_char;
use self::builder::*;
use std::string::String;
use std::sync::Arc;
use std::vec::Vec;

use parking_lot::Mutex;

Expand Down Expand Up @@ -60,49 +60,8 @@ impl Context {
/// assert!(Context::new(invalid_remapping).is_err());
/// ```
pub fn new(args: impl IntoIterator<Item = String>) -> Result<Self, RclrsError> {
// SAFETY: Getting a zero-initialized value is always safe
let mut rcl_context = unsafe { rcl_get_zero_initialized_context() };
let cstring_args: Vec<CString> = args
.into_iter()
.map(|arg| {
CString::new(arg.as_str()).map_err(|err| RclrsError::StringContainsNul {
err,
s: arg.clone(),
})
})
.collect::<Result<_, _>>()?;
// Vector of pointers into cstring_args
let c_args: Vec<*const c_char> = cstring_args.iter().map(|arg| arg.as_ptr()).collect();
unsafe {
// SAFETY: No preconditions for this function.
let allocator = rcutils_get_default_allocator();
// SAFETY: Getting a zero-initialized value is always safe.
let mut rcl_init_options = rcl_get_zero_initialized_init_options();
// SAFETY: Passing in a zero-initialized value is expected.
// In the case where this returns not ok, there's nothing to clean up.
rcl_init_options_init(&mut rcl_init_options, allocator).ok()?;
// SAFETY: This function does not store the ephemeral init_options and c_args
// pointers. Passing in a zero-initialized rcl_context is expected.
let ret = rcl_init(
c_args.len() as i32,
if c_args.is_empty() {
std::ptr::null()
} else {
c_args.as_ptr()
},
&rcl_init_options,
&mut rcl_context,
)
.ok();
// SAFETY: It's safe to pass in an initialized object.
// Early return will not leak memory, because this is the last fini function.
rcl_init_options_fini(&mut rcl_init_options).ok()?;
// Move the check after the last fini()
ret?;
}
Ok(Self {
rcl_context_mtx: Arc::new(Mutex::new(rcl_context)),
})
let builder = ContextBuilder::new(args)?;
builder.build()
}

/// Checks if the context is still valid.
Expand Down
71 changes: 71 additions & 0 deletions rclrs/src/context/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::error::ToResult;
use crate::rcl_bindings::*;
use crate::{Context, RclrsError};
use std::ffi::CString;
use std::sync::Arc;

use parking_lot::Mutex;
use std::os::raw::c_char;

pub struct ContextBuilder {
cstring_args: Vec<CString>,
init_options_mtx: Mutex<rcl_init_options_t>,
}

impl ContextBuilder {
/// Build a new ContextBuilder instance
pub fn new(args: impl IntoIterator<Item = String>) -> Result<ContextBuilder, RclrsError> {
Ok(ContextBuilder {
cstring_args: args
.into_iter()
.map(|arg| {
CString::new(arg.as_str()).map_err(|err| RclrsError::StringContainsNul {
err,
s: arg.clone(),
})
})
.collect::<Result<_, _>>()?,
// SAFETY: Getting a zero-initialized value is always safe.
init_options_mtx: unsafe { Mutex::new(rcl_get_zero_initialized_init_options()) },
})
}

/// Function to build the Context instance
pub fn build(&self) -> Result<Context, RclrsError> {
let mut rcl_init_options = self.init_options_mtx.lock();

let c_args: Vec<*const c_char> = self.cstring_args.iter().map(|arg| arg.as_ptr()).collect();
unsafe {
// SAFETY: Getting a zero-initialized value is always safe
let mut rcl_context: rcl_context_t = rcl_get_zero_initialized_context();
// SAFETY: No preconditions for this function.
let allocator: rcutils_allocator_t = rcutils_get_default_allocator();

// SAFETY: Passing in a zero-initialized value is expected.
// In the case where this returns not ok, there's nothing to clean up.
rcl_init_options_init(&mut *rcl_init_options, allocator).ok()?;
// SAFETY: This function does not store the ephemeral init_options and c_args
// pointers. Passing in a zero-initialized rcl_context is expected.

let ret = rcl_init(
c_args.len() as i32,
if c_args.is_empty() {
std::ptr::null()
} else {
c_args.as_ptr()
},
&*rcl_init_options,
&mut rcl_context,
)
.ok();
// SAFETY: It's safe to pass in an initialized object.
// Early return will not leak memory, because this is the last fini function.
rcl_init_options_fini(&mut *rcl_init_options).ok()?;
// Move the check after the last fini()
ret?;
Ok(Context {
rcl_context_mtx: Arc::new(Mutex::new(rcl_context)),
})
}
}
}