1
1
use std:: ops:: { Deref , DerefMut } ;
2
2
use defines:: AfError ;
3
3
use std:: error:: Error ;
4
- use std:: marker:: { Send , Sync } ;
5
4
use std:: sync:: RwLock ;
6
5
7
- /// Signature of callback function to be called to handle errors
8
- pub type ErrorCallback = Fn ( AfError ) ;
6
+ /// Signature of error handling callback function
7
+ pub type ErrorCallback = fn ( AfError ) ;
9
8
10
- /// Wrap ErrorCallback function pointer inside a structure
11
- /// to enable implementing Send, Sync traits on it.
12
- pub struct Callback < ' cblifetime > {
13
- ///Reference to a valid error callback function
14
- ///Make sure this callback stays relevant throughout the lifetime of application.
15
- pub cb : & ' cblifetime ErrorCallback ,
9
+ /// Structure holding handle to callback function
10
+ pub struct Callback {
11
+ cb : ErrorCallback ,
16
12
}
17
13
18
- // Implement Send, Sync traits for Callback structure to
19
- // enable the user of Callback function pointer in conjunction
20
- // with threads using a mutex.
21
- unsafe impl < ' cblifetime > Send for Callback < ' cblifetime > { }
22
- unsafe impl < ' cblifetime > Sync for Callback < ' cblifetime > { }
14
+ impl Callback {
15
+ /// Associated function to create a new Callback object
16
+ pub fn new ( callback : ErrorCallback ) -> Self {
17
+ Callback { cb : callback}
18
+ }
19
+
20
+ /// call invokes the error callback with `error_code`.
21
+ pub fn call ( & self , error_code : AfError ) {
22
+ ( self . cb ) ( error_code)
23
+ }
24
+ }
23
25
24
- pub const DEFAULT_HANDLE_ERROR : Callback < ' static > = Callback { cb : & handle_error_general} ;
26
+ /// Default error handling callback provided by ArrayFire crate
27
+ pub fn handle_error_general ( error_code : AfError ) {
28
+ match error_code {
29
+ AfError :: SUCCESS => { } , /* No-op */
30
+ _ => panic ! ( "Error message: {}" , error_code. description( ) ) ,
31
+ }
32
+ }
25
33
26
34
lazy_static ! {
27
- static ref ERROR_HANDLER_LOCK : RwLock < Callback < ' static > > =
28
- RwLock :: new( DEFAULT_HANDLE_ERROR ) ;
35
+ static ref ERROR_HANDLER_LOCK : RwLock < Callback > =
36
+ RwLock :: new( Callback :: new ( handle_error_general ) ) ;
29
37
}
30
38
31
39
/// Register user provided error handler
@@ -45,16 +53,17 @@ lazy_static! {
45
53
/// }
46
54
/// }
47
55
///
48
- /// pub const ERR_HANDLE: Callback<'static> = Callback{ cb: &handleError};
49
- ///
50
56
/// fn main() {
51
- /// register_error_handler(ERR_HANDLE);
57
+ /// //Registering the error handler should be the first call
58
+ /// //before any other functions are called if your version
59
+ /// //of error is to be used for subsequent function calls
60
+ /// register_error_handler(Callback::new(handleError));
52
61
///
53
62
/// info();
54
63
/// }
55
64
/// ```
56
65
#[ allow( unused_must_use) ]
57
- pub fn register_error_handler ( cb_value : Callback < ' static > ) {
66
+ pub fn register_error_handler ( cb_value : Callback ) {
58
67
let mut gaurd = match ERROR_HANDLER_LOCK . write ( ) {
59
68
Ok ( g) => g,
60
69
Err ( _) => panic ! ( "Failed to acquire lock to register error handler" ) ,
@@ -63,22 +72,12 @@ pub fn register_error_handler(cb_value: Callback<'static>) {
63
72
* gaurd. deref_mut ( ) = cb_value;
64
73
}
65
74
66
- /// Default error handling callback provided by ArrayFire crate
67
- pub fn handle_error_general ( error_code : AfError ) {
68
- match error_code {
69
- AfError :: SUCCESS => { } , /* No-op */
70
- _ => panic ! ( "Error message: {}" , error_code. description( ) ) ,
71
- }
72
- }
73
-
74
75
#[ allow( non_snake_case) ]
75
76
pub fn HANDLE_ERROR ( error_code : AfError ) {
76
77
let gaurd = match ERROR_HANDLER_LOCK . read ( ) {
77
78
Ok ( g) => g,
78
79
Err ( _) => panic ! ( "Failed to acquire lock while handling FFI return value" ) ,
79
80
} ;
80
81
81
- let func = gaurd. deref ( ) . cb ;
82
-
83
- func ( error_code) ;
82
+ ( * gaurd. deref ( ) ) . call ( error_code) ;
84
83
}
0 commit comments