@@ -36,48 +36,77 @@ use super::iterator::AsyncClientIntoIterator;
36
36
37
37
38
38
pub struct AsyncClient {
39
- handle : ffiasync:: MQTTAsync ,
40
- barrier : Barrier ,
41
- action_result : Option < Result < ( ) , CallbackError > > ,
42
- messages : Arc < Mutex < Vec < Message > > > ,
39
+ inner : Box < ImmovableClient >
43
40
}
44
41
45
42
impl AsyncClient {
43
+ pub fn new ( address : & str , clientid : & str , persistence : PersistenceType ) -> Result < Self , MqttError > {
44
+ let mut ac = AsyncClient {
45
+ inner : Box :: new ( ImmovableClient :: new ( address, clientid, persistence) )
46
+ } ;
47
+ try!( ac. inner . create ( ) ) ;
48
+ Ok ( ac)
49
+ }
50
+ pub fn connect ( & mut self , options : & AsyncConnectOptions ) -> Result < ( ) , MqttError > {
51
+ self . inner . connect ( options)
52
+ }
53
+ pub fn is_connected ( & self ) -> bool {
54
+ self . inner . is_connected ( )
55
+ }
56
+ pub fn send ( & mut self , data : & [ u8 ] , topic : & str , qos : Qos ) -> Result < ( ) , MqttError > {
57
+ self . inner . send ( data, topic, qos)
58
+ }
59
+ pub fn subscribe ( & mut self , topic : & str , qos : Qos ) -> Result < ( ) , MqttError > {
60
+ self . inner . subscribe ( topic, qos)
61
+ }
62
+ pub fn messages ( & mut self ) -> AsyncClientIntoIterator {
63
+ AsyncClientIntoIterator :: new ( self . inner . messages . clone ( ) )
64
+ }
65
+ }
66
+
46
67
47
- /// Ensures the FFI struct is consistent for callback invocation.
48
- ///
49
- /// Because the user may move this struct, the `context` pointer
50
- /// passed back to FFI callbacks might be invalidated. This function
51
- /// should be called before FFI actions that might fire callbacks to ensure
52
- /// the self-pointer is valid.
68
+ struct ImmovableClient {
69
+ c_url : CString ,
70
+ c_clientid : CString ,
71
+ handle : ffiasync:: MQTTAsync ,
72
+ persistence_context : c_void ,
73
+ persistence : PersistenceType ,
74
+
75
+ barrier : Barrier ,
76
+ action_result : Option < Result < ( ) , CallbackError > > ,
77
+ pub messages : Arc < Mutex < Vec < Message > > > ,
78
+ }
79
+ impl ImmovableClient {
53
80
fn context ( & mut self ) -> * mut c_void {
54
81
self as * mut _ as * mut c_void
55
82
}
56
83
57
- pub fn new ( address : & str , clientid : & str , persistence : PersistenceType ) -> Result < AsyncClient , MqttError > {
58
- let mut handle = unsafe { mem:: zeroed ( ) } ;
59
- let mut persistence_context: c_void = unsafe { mem:: zeroed ( ) } ;
60
-
61
- let c_url = CString :: new ( address) . unwrap ( ) ;
62
- let c_clientid = CString :: new ( clientid) . unwrap ( ) ;
63
- let array_url = c_url. as_bytes_with_nul ( ) ;
64
- let array_clientid = c_clientid. as_bytes_with_nul ( ) ;
84
+ pub fn new ( address : & str , clientid : & str , persistence : PersistenceType ) -> Self {
85
+ ImmovableClient {
86
+ c_url : CString :: new ( address) . unwrap ( ) ,
87
+ c_clientid : CString :: new ( clientid) . unwrap ( ) ,
88
+ handle : unsafe { mem:: zeroed ( ) } ,
89
+ persistence_context : unsafe { mem:: zeroed ( ) } ,
90
+ persistence : persistence,
91
+
92
+ barrier : Barrier :: new ( 2 ) ,
93
+ action_result : None ,
94
+ messages : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
95
+ }
96
+ }
65
97
98
+ pub fn create ( & mut self ) -> Result < ( ) , MqttError > {
99
+ let array_url = self . c_url . as_bytes_with_nul ( ) ;
100
+ let array_clientid = self . c_clientid . as_bytes_with_nul ( ) ;
66
101
let error = unsafe {
67
- ffiasync:: MQTTAsync_create ( & mut handle,
102
+ ffiasync:: MQTTAsync_create ( & mut self . handle ,
68
103
mem:: transmute :: < & u8 , * const c_char > ( & array_url[ 0 ] ) ,
69
104
mem:: transmute :: < & u8 , * const c_char > ( & array_clientid[ 0 ] ) ,
70
- persistence as i32 ,
71
- & mut persistence_context)
105
+ self . persistence as i32 ,
106
+ & mut self . persistence_context )
72
107
} ;
73
-
74
108
match error {
75
- 0 => { Ok ( AsyncClient {
76
- handle : handle,
77
- barrier : Barrier :: new ( 2 ) ,
78
- action_result : None ,
79
- messages : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
80
- } ) } ,
109
+ 0 => { Ok ( ( ) ) } ,
81
110
err => Err ( MqttError :: Create ( err) )
82
111
}
83
112
}
@@ -128,7 +157,7 @@ impl AsyncClient {
128
157
assert ! ( !context. is_null( ) ) ;
129
158
}
130
159
131
- pub fn is_connected ( & mut self ) -> bool {
160
+ pub fn is_connected ( & self ) -> bool {
132
161
let ret = unsafe {
133
162
ffiasync:: MQTTAsync_isConnected ( self . handle )
134
163
} ;
@@ -227,15 +256,15 @@ impl AsyncClient {
227
256
extern "C" fn action_succeeded ( context : * mut :: libc:: c_void , response : * mut ffiasync:: MQTTAsync_successData ) -> ( ) {
228
257
debug ! ( "success callback" ) ;
229
258
assert ! ( !context. is_null( ) ) ;
230
- let selfclient: & mut AsyncClient = unsafe { mem:: transmute ( context) } ;
259
+ let selfclient: & mut ImmovableClient = unsafe { mem:: transmute ( context) } ;
231
260
selfclient. action_result = Some ( Ok ( ( ) ) ) ;
232
261
selfclient. barrier . wait ( ) ;
233
262
}
234
263
235
264
extern "C" fn action_failed ( context : * mut :: libc:: c_void , response : * mut ffiasync:: MQTTAsync_failureData ) -> ( ) {
236
265
debug ! ( "failure callback" ) ;
237
266
assert ! ( !context. is_null( ) ) ;
238
- let selfclient : & mut AsyncClient = unsafe { mem:: transmute ( context) } ;
267
+ let selfclient : & mut ImmovableClient = unsafe { mem:: transmute ( context) } ;
239
268
if response. is_null ( ) {
240
269
selfclient. action_result = Some ( Err ( CallbackError :: NullPtr ) ) ;
241
270
} else {
@@ -264,7 +293,7 @@ impl AsyncClient {
264
293
} ;
265
294
266
295
assert ! ( !context. is_null( ) ) ;
267
- let selfclient : & mut AsyncClient = unsafe { mem:: transmute ( context) } ;
296
+ let selfclient : & mut ImmovableClient = unsafe { mem:: transmute ( context) } ;
268
297
269
298
let qos = Qos :: from_int ( transmessage. qos ) ;
270
299
@@ -297,12 +326,8 @@ impl AsyncClient {
297
326
1
298
327
}
299
328
300
- pub fn messages ( & mut self ) -> AsyncClientIntoIterator {
301
- AsyncClientIntoIterator :: new ( self . messages . clone ( ) )
302
- }
303
329
}
304
-
305
- impl Drop for AsyncClient {
330
+ impl Drop for ImmovableClient {
306
331
fn drop ( & mut self ) {
307
332
unsafe { ffiasync:: MQTTAsync_destroy ( & mut self . handle ) } ;
308
333
}
0 commit comments