@@ -7,6 +7,12 @@ import arc::methods;
7
7
8
8
// Things used by code generated by the pipe compiler.
9
9
export entangle, get_buffer, drop_buffer;
10
+ export send_packet_buffered, recv_packet_buffered;
11
+ export mk_packet;
12
+
13
+ // export these so we can find them in the buffer_resource
14
+ // destructor. This is probably another metadata bug.
15
+ export atomic_add_acq, atomic_sub_rel;
10
16
11
17
// User-level things
12
18
export send_packet, recv_packet, send, recv, try_recv, peek;
@@ -71,7 +77,7 @@ higher level buffer structure. Packets can maintain a pointer to their
71
77
buffer, and this is the part that gets freed.
72
78
73
79
It might be helpful to have some idea of a semi-unique pointer (like
74
- being partially pregnant, also like an ARC).
80
+ being partially pregnant, also like an ARC).
75
81
76
82
*/
77
83
@@ -87,7 +93,7 @@ class buffer_header {
87
93
// get away with restricting it to 0 or 1, if we're careful.
88
94
let mut ref_count : int;
89
95
90
- new ( ) { self . ref_count = 1 ; }
96
+ new ( ) { self . ref_count = 0 ; }
91
97
92
98
// We may want a drop, and to be careful about stringing this
93
99
// thing along.
@@ -134,13 +140,24 @@ class packet_header {
134
140
assert self. buffer . is_not_null ( ) ;
135
141
reinterpret_cast ( self . buffer )
136
142
}
143
+
144
+ fn set_buffer < T : send > ( b : ~buffer < T > ) unsafe {
145
+ self . buffer = reinterpret_cast ( b) ;
146
+ }
137
147
}
138
148
139
149
type packet< T : send > = {
140
150
header: packet_header,
141
151
mut payload: option<T >,
142
152
} ;
143
153
154
+ fn mk_packet < T : send > ( ) -> packet < T > {
155
+ {
156
+ header: packet_header ( ) ,
157
+ mut payload: none
158
+ }
159
+ }
160
+
144
161
fn unibuffer < T : send > ( ) -> ~buffer < packet < T > > {
145
162
let b = ~{
146
163
header: buffer_header ( ) ,
@@ -170,12 +187,25 @@ extern mod rusti {
170
187
fn atomic_xchng ( & dst: int , src : int ) -> int ;
171
188
fn atomic_xchng_acq ( & dst: int , src : int ) -> int ;
172
189
fn atomic_xchng_rel ( & dst: int , src : int ) -> int ;
190
+
191
+ fn atomic_add_acq ( & dst: int , src : int ) -> int ;
192
+ fn atomic_sub_rel ( & dst: int , src : int ) -> int ;
173
193
}
174
194
195
+ // If I call the rusti versions directly from a polymorphic function,
196
+ // I get link errors. This is a bug that needs investigated more.
175
197
fn atomic_xchng_rel ( & dst: int , src : int ) -> int {
176
198
rusti:: atomic_xchng_rel ( dst, src)
177
199
}
178
200
201
+ fn atomic_add_acq ( & dst: int , src : int ) -> int {
202
+ rusti:: atomic_add_acq ( dst, src)
203
+ }
204
+
205
+ fn atomic_sub_rel ( & dst: int , src : int ) -> int {
206
+ rusti:: atomic_sub_rel ( dst, src)
207
+ }
208
+
179
209
type rust_task = libc:: c_void ;
180
210
181
211
extern mod rustrt {
@@ -222,13 +252,21 @@ unsafe fn get_buffer<T: send>(p: *packet_header) -> ~buffer<T> {
222
252
class buffer_resource<T : send> {
223
253
let buffer: ~buffer < T > ;
224
254
new( +b: ~buffer<T >) {
255
+ let p = ptr:: addr_of ( * b) ;
256
+ #error ( "take %?" , p) ;
257
+ atomic_add_acq ( b. header . ref_count , 1 ) ;
225
258
self . buffer = b;
226
259
}
227
260
228
261
drop unsafe {
229
262
let b = move !{ self . buffer } ;
230
- let old_count = atomic_xchng_rel ( b. header . ref_count , 0 ) ;
231
- if old_count == 0 {
263
+ let p = ptr:: addr_of ( * b) ;
264
+ #error ( "drop %?" , p) ;
265
+ let old_count = atomic_sub_rel ( b. header . ref_count , 1 ) ;
266
+ //let old_count = atomic_xchng_rel(b.header.ref_count, 0);
267
+ if old_count == 1 {
268
+ // The new count is 0.
269
+
232
270
// go go gadget drop glue
233
271
}
234
272
else {
@@ -237,7 +275,8 @@ class buffer_resource<T: send> {
237
275
}
238
276
}
239
277
240
- fn send < T : send > ( -p : send_packet < T > , -payload : T ) {
278
+ fn send < T : send , Tbuffer : send > ( -p : send_packet_buffered < T , Tbuffer > ,
279
+ -payload : T ) {
241
280
let header = p. header ( ) ;
242
281
let p_ = p. unwrap ( ) ;
243
282
let p = unsafe { & * p_ } ;
@@ -273,11 +312,13 @@ fn send<T: send>(-p: send_packet<T>, -payload: T) {
273
312
}
274
313
}
275
314
276
- fn recv<T : send>( -p: recv_packet< T >) -> T {
315
+ fn recv<T : send, Tbuffer : send >( -p: recv_packet_buffered< T , Tbuffer >) -> T {
277
316
option : : unwrap ( try_recv ( p) )
278
317
}
279
318
280
- fn try_recv<T : send>( -p: recv_packet<T >) -> option<T > {
319
+ fn try_recv<T : send, Tbuffer : send>( -p: recv_packet_buffered<T , Tbuffer >)
320
+ -> option<T >
321
+ {
281
322
let p_ = p. unwrap ( ) ;
282
323
let p = unsafe { & * p_ } ;
283
324
let this = rustrt:: rust_get_task ( ) ;
@@ -498,6 +539,10 @@ class send_packet_buffered<T: send, Tbuffer: send> {
498
539
p <-> self . p ;
499
540
sender_terminate ( option:: unwrap ( p) )
500
541
}
542
+ unsafe { #error( "send_drop: %?" ,
543
+ if self . buffer == none {
544
+ "none"
545
+ } else { "some" } ) ; }
501
546
}
502
547
fn unwrap( ) -> * packet<T > {
503
548
let mut p = none;
@@ -518,6 +563,13 @@ class send_packet_buffered<T: send, Tbuffer: send> {
518
563
none { fail ~"packet already consumed" }
519
564
}
520
565
}
566
+
567
+ fn reuse_buffer ( ) -> buffer_resource < Tbuffer > {
568
+ #error ( "send reuse_buffer" ) ;
569
+ let mut tmp = none;
570
+ tmp <-> self . buffer ;
571
+ option:: unwrap ( tmp)
572
+ }
521
573
}
522
574
523
575
type recv_packet < T : send > = recv_packet_buffered < T , packet < T > > ;
@@ -547,6 +599,10 @@ class recv_packet_buffered<T: send, Tbuffer: send> : selectable {
547
599
p <-> self . p ;
548
600
receiver_terminate ( option:: unwrap ( p) )
549
601
}
602
+ unsafe { #error( "recv_drop: %?" ,
603
+ if self . buffer == none {
604
+ "none"
605
+ } else { "some" } ) ; }
550
606
}
551
607
fn unwrap( ) -> * packet<T > {
552
608
let mut p = none;
@@ -567,6 +623,13 @@ class recv_packet_buffered<T: send, Tbuffer: send> : selectable {
567
623
none { fail ~"packet already consumed" }
568
624
}
569
625
}
626
+
627
+ fn reuse_buffer ( ) -> buffer_resource < Tbuffer > {
628
+ #error ( "recv reuse_buffer" ) ;
629
+ let mut tmp = none;
630
+ tmp <-> self . buffer ;
631
+ option:: unwrap ( tmp)
632
+ }
570
633
}
571
634
572
635
fn entangle < T : send > ( ) -> ( send_packet < T > , recv_packet < T > ) {
0 commit comments