@@ -7,8 +7,16 @@ struct TestResource {
7
7
test_field : RwLock < i32 > ,
8
8
}
9
9
10
+ /// This one is designed to look more like pointer data, to increase the
11
+ /// chance of segfaults if the implementation is wrong.
12
+ struct ImmutableResource {
13
+ a : u32 ,
14
+ b : u32
15
+ }
16
+
10
17
pub fn on_load < ' a > ( env : NifEnv < ' a > ) -> bool {
11
18
resource_struct_init ! ( TestResource , env) ;
19
+ resource_struct_init ! ( ImmutableResource , env) ;
12
20
true
13
21
}
14
22
@@ -34,3 +42,39 @@ pub fn resource_get_integer_field<'a>(env: NifEnv<'a>, args: &Vec<NifTerm<'a>>)
34
42
let test_field = resource. test_field . read ( ) . unwrap ( ) ;
35
43
Ok ( test_field. encode ( env) )
36
44
}
45
+
46
+
47
+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
48
+
49
+ lazy_static ! {
50
+ static ref COUNT : AtomicUsize = AtomicUsize :: new( 0 ) ;
51
+ }
52
+
53
+ impl ImmutableResource {
54
+ fn new ( u : u32 ) -> ImmutableResource {
55
+ COUNT . fetch_add ( 1 , Ordering :: SeqCst ) ;
56
+ ImmutableResource {
57
+ a : u,
58
+ b : !u
59
+ }
60
+ }
61
+ }
62
+
63
+ impl Drop for ImmutableResource {
64
+ fn drop ( & mut self ) {
65
+ assert_eq ! ( self . a, !self . b) ;
66
+ self . b = self . a ;
67
+ COUNT . fetch_sub ( 1 , Ordering :: SeqCst ) ;
68
+ }
69
+ }
70
+
71
+ pub fn resource_make_immutable < ' a > ( env : NifEnv < ' a > , args : & Vec < NifTerm < ' a > > ) -> NifResult < NifTerm < ' a > > {
72
+ let u: u32 = try!( args[ 0 ] . decode ( ) ) ;
73
+ Ok ( ResourceCell :: new ( ImmutableResource :: new ( u) ) . encode ( env) )
74
+ }
75
+
76
+ /// Count how many instances of `ImmutableResource` are currently alive globally.
77
+ pub fn resource_immutable_count < ' a > ( env : NifEnv < ' a > , _args : & Vec < NifTerm < ' a > > ) -> NifResult < NifTerm < ' a > > {
78
+ let n = COUNT . load ( Ordering :: SeqCst ) as u32 ;
79
+ Ok ( n. encode ( env) )
80
+ }
0 commit comments