1
- use std:: ffi:: CStr ;
2
1
use std:: ffi:: CString ;
3
2
use std:: sync:: { Arc , Mutex } ;
4
3
@@ -9,7 +8,7 @@ use super::{
9
8
use crate :: error:: { RclrsError , ToResult } ;
10
9
use crate :: qos:: QoSProfile ;
11
10
use crate :: rcl_bindings:: * ;
12
- use crate :: NodeHandle ;
11
+ use crate :: { ENTITY_LIFECYCLE_MUTEX , PublisherHandle , NodeHandle } ;
13
12
14
13
/// Struct for sending messages of type `T`.
15
14
///
@@ -22,24 +21,13 @@ use crate::NodeHandle;
22
21
///
23
22
/// [1]: crate::spin
24
23
pub struct DynamicPublisher {
25
- rcl_publisher_mtx : Mutex < rcl_publisher_t > ,
26
- node_handle : Arc < NodeHandle > ,
24
+ handle : PublisherHandle ,
27
25
metadata : DynamicMessageMetadata ,
28
26
// This is the regular type support library, not the introspection one.
29
27
#[ allow( dead_code) ]
30
28
type_support_library : Arc < libloading:: Library > ,
31
29
}
32
30
33
- impl Drop for DynamicPublisher {
34
- fn drop ( & mut self ) {
35
- let mut rcl_node = self . node_handle . rcl_node . lock ( ) . unwrap ( ) ;
36
- unsafe {
37
- // SAFETY: No preconditions for this function (besides the arguments being valid).
38
- rcl_publisher_fini ( self . rcl_publisher_mtx . get_mut ( ) . unwrap ( ) , & mut * rcl_node) ;
39
- }
40
- }
41
- }
42
-
43
31
// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread
44
32
// they are running in. Therefore, this type can be safely sent to another thread.
45
33
// unsafe impl Send for DynamicPublisher {}
@@ -52,7 +40,7 @@ impl DynamicPublisher {
52
40
///
53
41
/// Node and namespace changes are always applied _before_ topic remapping.
54
42
pub ( crate ) fn new (
55
- node_handle : & Arc < NodeHandle > ,
43
+ node_handle : Arc < NodeHandle > ,
56
44
topic : & str ,
57
45
topic_type : MessageTypeName ,
58
46
qos : QoSProfile ,
@@ -81,30 +69,36 @@ impl DynamicPublisher {
81
69
err,
82
70
s : topic. into ( ) ,
83
71
} ) ?;
84
- let rcl_node = node_handle. rcl_node . lock ( ) . unwrap ( ) ;
85
72
86
73
// SAFETY: No preconditions for this function.
87
74
let mut publisher_options = unsafe { rcl_publisher_get_default_options ( ) } ;
88
75
publisher_options. qos = qos. into ( ) ;
89
- unsafe {
90
- // SAFETY: The rcl_publisher is zero-initialized as expected by this function.
91
- // The rcl_node is kept alive because it is co-owned by the subscription.
92
- // The topic name and the options are copied by this function, so they can be dropped
93
- // afterwards.
94
- // TODO: type support?
95
- rcl_publisher_init (
96
- & mut rcl_publisher,
97
- & * rcl_node,
98
- type_support_ptr,
99
- topic_c_string. as_ptr ( ) ,
100
- & publisher_options,
101
- )
102
- . ok ( ) ?;
76
+
77
+ {
78
+ let rcl_node = node_handle. rcl_node . lock ( ) . unwrap ( ) ;
79
+ let _lifecycle_lock = ENTITY_LIFECYCLE_MUTEX . lock ( ) . unwrap ( ) ;
80
+ unsafe {
81
+ // SAFETY: The rcl_publisher is zero-initialized as expected by this function.
82
+ // The rcl_node is kept alive because it is co-owned by the subscription.
83
+ // The topic name and the options are copied by this function, so they can be dropped
84
+ // afterwards.
85
+ // TODO: type support?
86
+ rcl_publisher_init (
87
+ & mut rcl_publisher,
88
+ & * rcl_node,
89
+ type_support_ptr,
90
+ topic_c_string. as_ptr ( ) ,
91
+ & publisher_options,
92
+ )
93
+ . ok ( ) ?;
94
+ }
103
95
}
104
96
105
97
Ok ( Self {
106
- rcl_publisher_mtx : Mutex :: new ( rcl_publisher) ,
107
- node_handle : node_handle. clone ( ) ,
98
+ handle : PublisherHandle {
99
+ rcl_publisher : Mutex :: new ( rcl_publisher) ,
100
+ node_handle,
101
+ } ,
108
102
metadata,
109
103
type_support_library,
110
104
} )
@@ -115,15 +109,12 @@ impl DynamicPublisher {
115
109
/// This returns the topic name after remapping, so it is not necessarily the
116
110
/// topic name which was used when creating the publisher.
117
111
pub fn topic_name ( & self ) -> String {
118
- // SAFETY: No preconditions for the functions called.
119
- // The unsafe variables created get converted to safe types before being returned
120
- unsafe {
121
- let raw_topic_pointer =
122
- rcl_publisher_get_topic_name ( & * self . rcl_publisher_mtx . lock ( ) . unwrap ( ) ) ;
123
- CStr :: from_ptr ( raw_topic_pointer)
124
- . to_string_lossy ( )
125
- . into_owned ( )
126
- }
112
+ self . handle . topic_name ( )
113
+ }
114
+
115
+ /// Returns the number of subscriptions of the publisher.
116
+ pub fn get_subscription_count ( & self ) -> Result < usize , RclrsError > {
117
+ self . handle . get_subscription_count ( )
127
118
}
128
119
129
120
/// Publishes a message.
@@ -135,7 +126,7 @@ impl DynamicPublisher {
135
126
if message. metadata . message_type != self . metadata . message_type {
136
127
return Err ( DynamicMessageError :: MessageTypeMismatch . into ( ) ) ;
137
128
}
138
- let rcl_publisher = & mut * self . rcl_publisher_mtx . lock ( ) . unwrap ( ) ;
129
+ let rcl_publisher = & mut * self . handle . rcl_publisher . lock ( ) . unwrap ( ) ;
139
130
unsafe {
140
131
// SAFETY: The message type is guaranteed to match the publisher type by the type system.
141
132
// The message does not need to be valid beyond the duration of this function call.
0 commit comments