@@ -26,46 +26,26 @@ io::println(comm::recv(p));
26
26
27
27
import either:: either;
28
28
29
+ export port:: { } ;
30
+ export chan:: { } ;
29
31
export send;
30
32
export recv;
31
- export recv_chan;
32
33
export peek;
34
+ export recv_chan;
33
35
export select2;
34
- export chan:: { } ;
35
- export port:: { } ;
36
36
37
- enum rust_port { }
38
37
39
- #[ abi = "cdecl" ]
40
- native mod rustrt {
41
- fn rust_port_id_send < T : send > ( target_port : port_id ,
42
- data : T ) -> libc:: uintptr_t ;
43
-
44
- fn new_port ( unit_sz : libc:: size_t ) -> * rust_port ;
45
- fn del_port ( po : * rust_port ) ;
46
- fn rust_port_begin_detach ( po : * rust_port ,
47
- yield : * libc:: uintptr_t ) ;
48
- fn rust_port_end_detach ( po : * rust_port ) ;
49
- fn get_port_id ( po : * rust_port ) -> port_id ;
50
- fn rust_port_size ( po : * rust_port ) -> libc:: size_t ;
51
- fn port_recv ( dptr : * uint , po : * rust_port ,
52
- yield : * libc:: uintptr_t ) ;
53
- fn rust_port_select ( dptr : * * rust_port , ports : * * rust_port ,
54
- n_ports : libc:: size_t ,
55
- yield : * libc:: uintptr_t ) ;
56
- fn rust_port_take ( port_id : port_id ) -> * rust_port ;
57
- fn rust_port_drop ( p : * rust_port ) ;
58
- fn rust_port_task ( p : * rust_port ) -> libc:: uintptr_t ;
59
- fn get_task_id ( ) -> libc:: uintptr_t ;
60
- }
38
+ #[ doc = "
39
+ A communication endpoint that can receive messages
61
40
62
- #[ abi = "rust-intrinsic" ]
63
- native mod rusti {
64
- fn init < T > ( ) -> T ;
41
+ Each port has a unique per-task identity and may not be replicated or
42
+ transmitted. If a port value is copied, both copies refer to the same
43
+ port. Ports may be associated with multiple `chan`s.
44
+ " ]
45
+ enum port < T : send > {
46
+ port_t( @port_ptr < T > )
65
47
}
66
48
67
- type port_id = int ;
68
-
69
49
// It's critical that this only have one variant, so it has a record
70
50
// layout, and will work in the rust_task structure in task.rs.
71
51
#[ doc = "
@@ -82,35 +62,18 @@ enum chan<T: send> {
82
62
chan_t( port_id )
83
63
}
84
64
85
- resource port_ptr<T : send>( po: * rust_port) {
86
- // Once the port is detached it's guaranteed not to receive further
87
- // messages
88
- let yield = 0 u;
89
- let yieldp = ptr:: addr_of ( yield ) ;
90
- rustrt:: rust_port_begin_detach ( po, yieldp) ;
91
- if yield != 0 u {
92
- // Need to wait for the port to be detached
93
- // FIXME: If this fails then we're going to leave our port
94
- // in a bogus state. (Issue #1988)
95
- task:: yield ( ) ;
96
- }
97
- rustrt:: rust_port_end_detach ( po) ;
98
-
99
- // Drain the port so that all the still-enqueued items get dropped
100
- while rustrt:: rust_port_size ( po) > 0 u {
101
- recv_ :: < T > ( po) ;
102
- }
103
- rustrt:: del_port ( po) ;
65
+ #[ doc = "Constructs a port" ]
66
+ fn port < T : send > ( ) -> port < T > {
67
+ port_t ( @port_ptr ( rustrt:: new_port ( sys:: size_of :: < T > ( ) ) ) )
104
68
}
105
69
106
70
#[ doc = "
107
- A communication endpoint that can receive messages
108
-
109
- Each port has a unique per-task identity and may not be replicated or
110
- transmitted. If a port value is copied, both copies refer to the same
111
- port. Ports may be associated with multiple `chan`s.
71
+ Constructs a channel. The channel is bound to the port used to
72
+ construct it.
112
73
" ]
113
- enum port < T : send > { port_t( @port_ptr < T > ) }
74
+ fn chan < T : send > ( p : port < T > ) -> chan < T > {
75
+ chan_t ( rustrt:: get_port_id ( * * * p) )
76
+ }
114
77
115
78
#[ doc = "
116
79
Sends data over a channel. The sent data is moved into the channel,
@@ -126,17 +89,39 @@ fn send<T: send>(ch: chan<T>, -data: T) {
126
89
task:: yield ( ) ;
127
90
}
128
91
129
- #[ doc = "Constructs a port" ]
130
- fn port < T : send > ( ) -> port < T > {
131
- port_t ( @port_ptr ( rustrt:: new_port ( sys:: size_of :: < T > ( ) ) ) )
132
- }
133
-
134
92
#[ doc = "
135
93
Receive from a port. If no data is available on the port then the
136
94
task will block until data becomes available.
137
95
" ]
138
96
fn recv < T : send > ( p : port < T > ) -> T { recv_ ( * * * p) }
139
97
98
+ #[ doc = "Returns true if there are messages available" ]
99
+ fn peek < T : send > ( p : port < T > ) -> bool {
100
+ rustrt:: rust_port_size ( * * * p) != 0 u as libc:: size_t
101
+ }
102
+
103
+ resource port_ptr<T : send>( po: * rust_port) {
104
+ // Once the port is detached it's guaranteed not to receive further
105
+ // messages
106
+ let yield = 0 u;
107
+ let yieldp = ptr:: addr_of ( yield ) ;
108
+ rustrt:: rust_port_begin_detach ( po, yieldp) ;
109
+ if yield != 0 u {
110
+ // Need to wait for the port to be detached
111
+ // FIXME: If this fails then we're going to leave our port
112
+ // in a bogus state. (Issue #1988)
113
+ task:: yield ( ) ;
114
+ }
115
+ rustrt:: rust_port_end_detach ( po) ;
116
+
117
+ // Drain the port so that all the still-enqueued items get dropped
118
+ while rustrt:: rust_port_size ( po) > 0 u {
119
+ recv_ :: < T > ( po) ;
120
+ }
121
+ rustrt:: del_port ( po) ;
122
+ }
123
+
124
+
140
125
#[ doc( hidden) ]
141
126
fn recv_chan < T : send > ( ch : comm:: chan < T > ) -> T {
142
127
resource portref( p: * rust_port) {
@@ -210,19 +195,46 @@ fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
210
195
}
211
196
}
212
197
213
- #[ doc = "Returns true if there are messages available" ]
214
- fn peek < T : send > ( p : port < T > ) -> bool {
215
- rustrt:: rust_port_size ( * * * p) != 0 u as libc:: size_t
198
+
199
+ /* Implementation details */
200
+
201
+
202
+ enum rust_port { }
203
+
204
+ type port_id = int ;
205
+
206
+ #[ abi = "cdecl" ]
207
+ native mod rustrt {
208
+ fn rust_port_id_send < T : send > ( target_port : port_id ,
209
+ data : T ) -> libc:: uintptr_t ;
210
+
211
+ fn new_port ( unit_sz : libc:: size_t ) -> * rust_port ;
212
+ fn del_port ( po : * rust_port ) ;
213
+ fn rust_port_begin_detach ( po : * rust_port ,
214
+ yield : * libc:: uintptr_t ) ;
215
+ fn rust_port_end_detach ( po : * rust_port ) ;
216
+ fn get_port_id ( po : * rust_port ) -> port_id ;
217
+ fn rust_port_size ( po : * rust_port ) -> libc:: size_t ;
218
+ fn port_recv ( dptr : * uint , po : * rust_port ,
219
+ yield : * libc:: uintptr_t ) ;
220
+ fn rust_port_select ( dptr : * * rust_port , ports : * * rust_port ,
221
+ n_ports : libc:: size_t ,
222
+ yield : * libc:: uintptr_t ) ;
223
+ fn rust_port_take ( port_id : port_id ) -> * rust_port ;
224
+ fn rust_port_drop ( p : * rust_port ) ;
225
+ fn rust_port_task ( p : * rust_port ) -> libc:: uintptr_t ;
226
+ fn get_task_id ( ) -> libc:: uintptr_t ;
216
227
}
217
228
218
- #[ doc = "
219
- Constructs a channel. The channel is bound to the port used to
220
- construct it.
221
- " ]
222
- fn chan < T : send > ( p : port < T > ) -> chan < T > {
223
- chan_t ( rustrt:: get_port_id ( * * * p) )
229
+ #[ abi = "rust-intrinsic" ]
230
+ native mod rusti {
231
+ fn init < T > ( ) -> T ;
224
232
}
225
233
234
+
235
+ /* Tests */
236
+
237
+
226
238
#[ test]
227
239
fn create_port_and_chan ( ) { let p = port :: < int > ( ) ; chan ( p) ; }
228
240
0 commit comments