pub struct CffiSession { /* private fields */ }Expand description
Session backed by a C vtable.
Implementations§
Source§impl CffiSession
impl CffiSession
Sourcepub fn domain_id(&self) -> u32
pub fn domain_id(&self) -> u32
Domain this session was opened on. Authoritative: it is the value the backend actually got, not a re-derivation that can disagree with it.
Sourcepub fn serialization_format_cstr(&self) -> *const c_char
pub fn serialization_format_cstr(&self) -> *const c_char
RFC-0088 D4 / phase-421 W2 — the serialization format THIS session’s
backend speaks, as a NUL-terminated C string with 'static lifetime,
or NULL when the backend does not declare one.
Not <Self as Session>::SERIALIZATION_FORMAT. That const is the
trait default, "cdr", and it is a lie for this type specifically:
CffiSession is the one session that does not know its own backend at
compile time — the vtable arrives at run time through
nros_rmw_cffi_register_named, and an image may register several. The
per-session answer therefore has to come from the vtable, which is the
whole reason the slot got a body.
A NULL slot answers NULL rather than "cdr": a backend that declines
to say what it speaks has not said "cdr", and guessing on its behalf
is the mistake get_implementation_identifier’s doc made for two
phases (corrected phase-393 W2). Every in-tree backend fills the slot,
so NULL means a foreign or pre-phase-421 vtable.
Sourcepub fn serialization_format(&self) -> Option<&'static str>
pub fn serialization_format(&self) -> Option<&'static str>
serialization_format_cstr as a
Rust string. None for a NULL slot or a non-UTF-8 answer.
Sourcepub fn open(
locator: &str,
mode: u8,
domain_id: u32,
node_name: &str,
) -> Result<Self, TransportError>
pub fn open( locator: &str, mode: u8, domain_id: u32, node_name: &str, ) -> Result<Self, TransportError>
Open a new session via the default registered vtable (first entry in the registry — the RMW_IMPLEMENTATION-style fast path for single-backend builds).
For explicit backend selection in multi-backend (bridge)
binaries, use open_named.
Sourcepub fn open_with_properties(
locator: &str,
mode: u8,
domain_id: u32,
node_name: &str,
properties: &[(&str, &str)],
) -> Result<Self, TransportError>
pub fn open_with_properties( locator: &str, mode: u8, domain_id: u32, node_name: &str, properties: &[(&str, &str)], ) -> Result<Self, TransportError>
phase-206 W3 — open a session carrying backend-specific configuration
properties (RmwConfig::properties across the C seam).
This is the rung that was missing. RmwConfig has carried
properties since it existed and every Rust backend reads them, but
nothing between the runtime and the vtable passed them on: this
function’s non-properties sibling handed create_session a NULL
options pointer, and the Rust-backend adapter on the far side built
properties: &[] unconditionally. So the only way to set a zenoh
listen endpoint, a TLS certificate or a scouting timeout was to build
an RmwConfig by hand in hosted Rust — a C or C++ image could state
none of it, on any platform.
Refused, never truncated: more than RMW_SESSION_MAX_PROPERTIES
entries, an empty key or value, or either longer than
SESSION_PROPERTY_BUF_LEN. All are TransportError::InvalidArgument.
Sourcepub fn open_named(
rmw_name: &str,
locator: &str,
mode: u8,
domain_id: u32,
node_name: &str,
) -> Result<Self, TransportError>
pub fn open_named( rmw_name: &str, locator: &str, mode: u8, domain_id: u32, node_name: &str, ) -> Result<Self, TransportError>
Phase 104.C.1 — open a new session against a named backend.
Resolves rmw_name against the registry (Phase 104.B.2),
returns Err(TransportError::InvalidArgument) if no backend
is registered under that name.
Sourcepub fn open_named_with_properties(
rmw_name: &str,
locator: &str,
mode: u8,
domain_id: u32,
node_name: &str,
properties: &[(&str, &str)],
) -> Result<Self, TransportError>
pub fn open_named_with_properties( rmw_name: &str, locator: &str, mode: u8, domain_id: u32, node_name: &str, properties: &[(&str, &str)], ) -> Result<Self, TransportError>
open_named carrying backend-specific
configuration properties — see open_with_properties.
Trait Implementations§
Source§impl Drop for CffiSession
impl Drop for CffiSession
Source§impl Session for CffiSession
impl Session for CffiSession
Source§fn serialization_format(&self) -> &'static str
fn serialization_format(&self) -> &'static str
The backend is chosen at run time here, so the trait’s compile-time default would be a guess. Ask the vtable, and fall back to the constant only for a backend that installed no body — which reads as “this backend has not said”, not as “cdr”.
Source§fn get_node_names(
&mut self,
visit: &mut dyn FnMut(&str, &str, Option<&str>) -> bool,
) -> Result<(), TransportError>
fn get_node_names( &mut self, visit: &mut dyn FnMut(&str, &str, Option<&str>) -> bool, ) -> Result<(), TransportError>
phase-381 W5/W6 — forward to the backend’s slot; NULL means UNSUPPORTED.
Without this the graph slots were unreachable for every C backend: the
trait default returns Unsupported, so a wired slot — cyclone’s, as of
W5 — would never be called and would look implemented while being dead
code. That is exactly the “a slot exists, therefore it works”
overstatement issue 0800 measured, one layer above where 0800 found it.
NULL surfaces Unsupported rather than an empty enumeration, which is
W6’s requirement: XRCE has no graph and must say “cannot tell you”, not
“nothing is there”.
Source§fn get_topic_names_and_types(
&mut self,
visit: &mut dyn FnMut(&str, &[&str]) -> bool,
) -> Result<(), TransportError>
fn get_topic_names_and_types( &mut self, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>
phase-381 / issue 0903 — the REST of the graph family.
W5 added get_node_names here and stopped, which made this the same
defect one method wide: every other graph call fell through to the trait
default and returned Unsupported, so the zenoh backend — which reaches
the runtime through this vtable — answered node names and NOTHING else.
Measured against a live rmw_zenoh_cpp talker: node enumeration worked
and get_topic_names_and_types returned empty, because the entity query
was never even STARTED.
Fixing one method of eleven is how the first version passed every unit test in the phase.
Source§fn get_names_and_types_by_node(
&mut self,
kind: GraphEntityKind,
node_name: &str,
node_namespace: &str,
visit: &mut dyn FnMut(&str, &[&str]) -> bool,
) -> Result<(), TransportError>
fn get_names_and_types_by_node( &mut self, kind: GraphEntityKind, node_name: &str, node_namespace: &str, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>
phase-381 W4, wired here by the live acceptance run.
The zenoh shim implemented this and get_endpoint_info_by_topic all
along; CffiSession never dispatched them, so both fell through to the
trait default and every caller got Unsupported. That is issue 0903’s
third defect for the SIX slots the 0903 fix did not cover — it wired the
five that had a failing symptom in front of it and left these, and
check-rmw-slot-producers calls them produced either way because it
asks whether a slot has a producer, not whether anything reaches it.
Found by graph_interop.rs on its first run against a real peer, which
is the only place it could have been found.
Source§fn get_endpoint_info_by_topic(
&mut self,
publishers: bool,
topic_name: &str,
visit: &mut dyn FnMut(&GraphEndpointInfo<'_>) -> bool,
) -> Result<(), TransportError>
fn get_endpoint_info_by_topic( &mut self, publishers: bool, topic_name: &str, visit: &mut dyn FnMut(&GraphEndpointInfo<'_>) -> bool, ) -> Result<(), TransportError>
The endpoints on a topic — see Self::get_names_and_types_by_node for
why this was unreachable until the live run.
Source§fn supported_qos_policies(&self) -> QoSPolicyMask
fn supported_qos_policies(&self) -> QoSPolicyMask
Phase 115.K.2.5.1.2 — declare a permissive QoS-policy mask
here so backends behind the cffi vtable don’t get rejected by
the runtime’s pre-validate step before they ever see the
create_publisher / create_subscription call. The vtable
doesn’t expose a per-backend policy mask yet; until it does,
the cffi route has to assume the registered backend supports
the union of every policy any nros-supported RMW honours.
Backends that don’t support a policy MUST surface
NROS_RMW_RET_INCOMPATIBLE_QOS from create_publisher etc.
to keep the no-silent-degradation contract.
TODO 115.K.2.x: extend nros_rmw_vtable_t with a
supported_qos_policies() callback so the runtime queries
the backend instead of guessing.
Source§type Error = TransportError
type Error = TransportError
Source§type PublisherHandle = CffiPublisher
type PublisherHandle = CffiPublisher
Source§type SubscriptionHandle = CffiSubscription
type SubscriptionHandle = CffiSubscription
Source§type ServiceHandle = CffiService
type ServiceHandle = CffiService
Source§type ClientHandle = CffiClient
type ClientHandle = CffiClient
Source§fn create_publisher(
&mut self,
topic: &TopicInfo<'_>,
qos: QoSProfile,
) -> Result<CffiPublisher, TransportError>
fn create_publisher( &mut self, topic: &TopicInfo<'_>, qos: QoSProfile, ) -> Result<CffiPublisher, TransportError>
Source§fn create_subscription(
&mut self,
topic: &TopicInfo<'_>,
qos: QoSProfile,
) -> Result<CffiSubscription, TransportError>
fn create_subscription( &mut self, topic: &TopicInfo<'_>, qos: QoSProfile, ) -> Result<CffiSubscription, TransportError>
Source§fn create_service(
&mut self,
service: &ServiceInfo<'_>,
qos: QoSProfile,
) -> Result<CffiService, TransportError>
fn create_service( &mut self, service: &ServiceInfo<'_>, qos: QoSProfile, ) -> Result<CffiService, TransportError>
ServiceTrait::take_request. Read moreSource§fn create_client(
&mut self,
service: &ServiceInfo<'_>,
qos: QoSProfile,
) -> Result<CffiClient, TransportError>
fn create_client( &mut self, service: &ServiceInfo<'_>, qos: QoSProfile, ) -> Result<CffiClient, TransportError>
Source§fn close(&mut self) -> Result<(), TransportError>
fn close(&mut self) -> Result<(), TransportError>
Source§fn drive_io(&mut self, timeout_ms: i32) -> Result<(), TransportError>
fn drive_io(&mut self, timeout_ms: i32) -> Result<(), TransportError>
Source§fn next_deadline_ms(&self) -> Option<u32>
fn next_deadline_ms(&self) -> Option<u32>
Source§unsafe fn set_wake_callback(
&mut self,
cb: Option<unsafe extern "C" fn(ctx: *mut c_void)>,
ctx: *mut c_void,
)
unsafe fn set_wake_callback( &mut self, cb: Option<unsafe extern "C" fn(ctx: *mut c_void)>, ctx: *mut c_void, )
cb.is_none()) the
executor wake callback. The runtime calls this once per
session after open with cb pointing at a runtime-owned
function and ctx pointing at the executor’s wake state.
The backend stores (cb, ctx) in its per-session state and
calls cb(ctx) whenever its transport notification path
fires (datagram arrival, condvar wake, etc.) — the runtime
cb does flag-write + condvar-signal atomically, so a
spin_once blocked on the wake condvar resumes immediately
instead of waiting for the next poll iteration. Read moreSource§fn supports_wake_callback(&self) -> bool
fn supports_wake_callback(&self) -> bool
set_wake_callback? Read moreSource§fn get_service_names_and_types(
&mut self,
visit: &mut dyn FnMut(&str, &[&str]) -> bool,
) -> Result<(), TransportError>
fn get_service_names_and_types( &mut self, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>
Self::get_topic_names_and_types, over servers and clients.Source§fn count_publishers(
&mut self,
topic_name: &str,
) -> Result<usize, TransportError>
fn count_publishers( &mut self, topic_name: &str, ) -> Result<usize, TransportError>
topic_name. Read moreSource§fn count_subscribers(
&mut self,
topic_name: &str,
) -> Result<usize, TransportError>
fn count_subscribers( &mut self, topic_name: &str, ) -> Result<usize, TransportError>
topic_name.
See Self::count_publishers for the caveats.Source§fn ping_session(&mut self, timeout_ms: i32) -> Result<(), TransportError>
fn ping_session(&mut self, timeout_ms: i32) -> Result<(), TransportError>
Source§const SERIALIZATION_FORMAT: &'static str = _
const SERIALIZATION_FORMAT: &'static str = _
rmw_get_serialization_format() reports it (“One middleware can only
have one encoding”). Read moreSource§const SERIALIZATION_FORMAT_ID: SerializationFormatId = nros_serdes::format::SerializationFormatId::Cdr
const SERIALIZATION_FORMAT_ID: SerializationFormatId = nros_serdes::format::SerializationFormatId::Cdr
Self::SERIALIZATION_FORMAT. Never
persisted, never compared across images — see nros_serdes::format.