@@ -7,6 +7,7 @@ export min_align_of;
7
7
export pref_align_of;
8
8
export refcount;
9
9
export log_str;
10
+ export lock_and_signal, condition, methods;
10
11
11
12
enum type_desc = {
12
13
first_param: * * libc:: c_int,
@@ -15,11 +16,20 @@ enum type_desc = {
15
16
// Remaining fields not listed
16
17
} ;
17
18
19
+ type rust_cond_lock = * libc:: c_void ;
20
+
18
21
#[ abi = "cdecl" ]
19
22
native mod rustrt {
20
23
pure fn refcount ( t : * ( ) ) -> libc:: intptr_t ;
21
24
fn unsupervise ( ) ;
22
25
pure fn shape_log_str ( t : * sys:: type_desc , data : * ( ) ) -> str ;
26
+
27
+ fn rust_create_cond_lock ( ) -> rust_cond_lock ;
28
+ fn rust_destroy_cond_lock ( lock : rust_cond_lock ) ;
29
+ fn rust_lock_cond_lock ( lock : rust_cond_lock ) ;
30
+ fn rust_unlock_cond_lock ( lock : rust_cond_lock ) ;
31
+ fn rust_wait_cond_lock ( lock : rust_cond_lock ) ;
32
+ fn rust_signal_cond_lock ( lock : rust_cond_lock ) -> bool ;
23
33
}
24
34
25
35
#[ abi = "rust-intrinsic" ]
@@ -74,8 +84,50 @@ pure fn log_str<T>(t: T) -> str {
74
84
}
75
85
}
76
86
87
+ resource lock_and_signal ( lock: rust_cond_lock) {
88
+ rustrt:: rust_destroy_cond_lock ( lock) ;
89
+ }
90
+
91
+ enum condition {
92
+ condition_( rust_cond_lock )
93
+ }
94
+
95
+ resource unlock( lock: rust_cond_lock) {
96
+ rustrt:: rust_unlock_cond_lock ( lock) ;
97
+ }
98
+
99
+ fn create_lock ( ) -> lock_and_signal {
100
+ lock_and_signal ( rustrt:: rust_create_cond_lock ( ) )
101
+ }
102
+
103
+ impl methods for lock_and_signal {
104
+ fn lock < T > ( f : fn ( ) -> T ) -> T {
105
+ rustrt:: rust_lock_cond_lock ( * self ) ;
106
+ let _r = unlock ( * self ) ;
107
+ f ( )
108
+ }
109
+
110
+ fn lock_cond < T > ( f : fn ( condition ) -> T ) -> T {
111
+ rustrt:: rust_lock_cond_lock ( * self ) ;
112
+ let _r = unlock ( * self ) ;
113
+ f ( condition_ ( * self ) )
114
+ }
115
+ }
116
+
117
+ impl methods for condition {
118
+ fn wait ( ) {
119
+ rustrt:: rust_wait_cond_lock ( * self ) ;
120
+ }
121
+
122
+ fn signal ( ) -> bool {
123
+ rustrt:: rust_signal_cond_lock ( * self )
124
+ }
125
+ }
126
+
77
127
#[ cfg( test) ]
78
128
mod tests {
129
+ use std;
130
+ import std:: arc;
79
131
80
132
#[ test]
81
133
fn size_of_basic ( ) {
@@ -121,6 +173,26 @@ mod tests {
121
173
assert pref_align_of :: < uint > ( ) == 8 u;
122
174
assert pref_align_of :: < * uint > ( ) == 8 u;
123
175
}
176
+
177
+ #[ test]
178
+ fn condition_variable ( ) {
179
+ let lock = arc:: arc ( create_lock ( ) ) ;
180
+ let lock2 = arc:: clone ( & lock) ;
181
+
182
+ task:: spawn { |move lock2|
183
+ let lock = arc:: get ( & lock2) ;
184
+ ( * lock) . lock_cond { |c|
185
+ c. wait ( ) ;
186
+ }
187
+ }
188
+
189
+ let mut signaled = false ;
190
+ while !signaled {
191
+ ( * arc:: get ( & lock) ) . lock_cond { |c|
192
+ signaled = c. signal ( )
193
+ }
194
+ }
195
+ }
124
196
}
125
197
126
198
// Local Variables:
0 commit comments