@@ -33,6 +33,7 @@ export recv;
33
33
export peek;
34
34
export recv_chan;
35
35
export select2;
36
+ export methods;
36
37
37
38
38
39
#[ doc = "
@@ -67,37 +68,22 @@ fn port<T: send>() -> port<T> {
67
68
port_t ( @port_ptr ( rustrt:: new_port ( sys:: size_of :: < T > ( ) ) ) )
68
69
}
69
70
70
- #[ doc = "
71
- Constructs a channel. The channel is bound to the port used to
72
- construct it.
73
- " ]
74
- fn chan < T : send > ( p : port < T > ) -> chan < T > {
75
- chan_t ( rustrt:: get_port_id ( * * * p) )
76
- }
71
+ impl methods < T : send > for port < T > {
72
+
73
+ fn chan ( ) -> chan < T > { chan ( self ) }
74
+ fn send ( +v : T ) { self . chan ( ) . send ( v) }
75
+ fn recv ( ) -> T { recv ( self ) }
76
+ fn peek ( ) -> bool { peek ( self ) }
77
77
78
- #[ doc = "
79
- Sends data over a channel. The sent data is moved into the channel,
80
- whereupon the caller loses access to it.
81
- " ]
82
- fn send < T : send > ( ch : chan < T > , -data : T ) {
83
- let chan_t( p) = ch;
84
- let res = rustrt:: rust_port_id_send ( p, data) ;
85
- if res != 0 u unsafe {
86
- // Data sent successfully
87
- unsafe :: forget ( data) ;
88
- }
89
- task:: yield ( ) ;
90
78
}
91
79
92
- #[ doc = "
93
- Receive from a port. If no data is available on the port then the
94
- task will block until data becomes available.
95
- " ]
96
- fn recv < T : send > ( p : port < T > ) -> T { recv_ ( * * * p) }
80
+ impl methods < T : send > for chan < T > {
81
+
82
+ fn chan ( ) -> chan < T > { self }
83
+ fn send ( +v : T ) { send ( self , v) }
84
+ fn recv ( ) -> T { recv_chan ( self ) }
85
+ fn peek ( ) -> bool { peek_chan ( self ) }
97
86
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
87
}
102
88
103
89
resource port_ptr<T : send>( po: * rust_port) {
@@ -121,9 +107,15 @@ resource port_ptr<T: send>(po: *rust_port) {
121
107
rustrt:: del_port ( po) ;
122
108
}
123
109
110
+ #[ doc = "
111
+ Internal function for converting from a channel to a port
124
112
125
- #[ doc( hidden) ]
126
- fn recv_chan < T : send > ( ch : comm:: chan < T > ) -> T {
113
+ # Failure
114
+
115
+ Fails if the port is detached or dead. Fails if the port
116
+ is owned by a different task.
117
+ " ]
118
+ fn as_raw_port < T : send , U > ( ch : comm:: chan < T > , f : fn ( * rust_port ) -> U ) -> U {
127
119
resource portref( p: * rust_port) {
128
120
if !ptr:: is_null ( p) {
129
121
rustrt:: rust_port_drop ( p) ;
@@ -135,10 +127,50 @@ fn recv_chan<T: send>(ch: comm::chan<T>) -> T {
135
127
if ptr:: is_null ( * p) {
136
128
fail "unable to locate port for channel"
137
129
} else if rustrt:: get_task_id ( ) != rustrt:: rust_port_task ( * p) {
138
- fail "attempting to receive on unowned channel "
130
+ fail "unable to access unowned port "
139
131
}
140
132
141
- recv_ ( * p)
133
+ f ( * p)
134
+ }
135
+
136
+ #[ doc = "
137
+ Constructs a channel. The channel is bound to the port used to
138
+ construct it.
139
+ " ]
140
+ fn chan < T : send > ( p : port < T > ) -> chan < T > {
141
+ chan_t ( rustrt:: get_port_id ( * * * p) )
142
+ }
143
+
144
+ #[ doc = "
145
+ Sends data over a channel. The sent data is moved into the channel,
146
+ whereupon the caller loses access to it.
147
+ " ]
148
+ fn send < T : send > ( ch : chan < T > , -data : T ) {
149
+ let chan_t( p) = ch;
150
+ let res = rustrt:: rust_port_id_send ( p, data) ;
151
+ if res != 0 u unsafe {
152
+ // Data sent successfully
153
+ unsafe :: forget ( data) ;
154
+ }
155
+ task:: yield ( ) ;
156
+ }
157
+
158
+ #[ doc = "
159
+ Receive from a port. If no data is available on the port then the
160
+ task will block until data becomes available.
161
+ " ]
162
+ fn recv < T : send > ( p : port < T > ) -> T { recv_ ( * * * p) }
163
+
164
+ #[ doc = "Returns true if there are messages available" ]
165
+ fn peek < T : send > ( p : port < T > ) -> bool { peek_ ( * * * p) }
166
+
167
+ #[ doc( hidden) ]
168
+ fn recv_chan < T : send > ( ch : comm:: chan < T > ) -> T {
169
+ as_raw_port ( ch, recv_ ( _) )
170
+ }
171
+
172
+ fn peek_chan < T : send > ( ch : comm:: chan < T > ) -> bool {
173
+ as_raw_port ( ch, peek_ ( _) )
142
174
}
143
175
144
176
#[ doc = "Receive on a raw port pointer" ]
@@ -160,6 +192,10 @@ fn recv_<T: send>(p: *rust_port) -> T {
160
192
ret res;
161
193
}
162
194
195
+ fn peek_ ( p : * rust_port ) -> bool unsafe {
196
+ rustrt:: rust_port_size ( p) != 0 u as libc:: size_t
197
+ }
198
+
163
199
#[ doc = "Receive on one of two ports" ]
164
200
fn select2 < A : send , B : send > ( p_a : port < A > , p_b : port < B > )
165
201
-> either < A , B > unsafe {
@@ -391,3 +427,18 @@ fn test_recv_chan_wrong_task() {
391
427
recv_chan ( ch)
392
428
} )
393
429
}
430
+
431
+ #[ test]
432
+ fn test_port_send ( ) {
433
+ let po = port ( ) ;
434
+ po. send ( ( ) ) ;
435
+ po. recv ( ) ;
436
+ }
437
+
438
+ #[ test]
439
+ fn test_chan_peek ( ) {
440
+ let po = port ( ) ;
441
+ let ch = po. chan ( ) ;
442
+ ch. send ( ( ) ) ;
443
+ assert ch. peek ( ) ;
444
+ }
0 commit comments