1#[macro_export]
49macro_rules! go {
50 ($body:expr) => {{
51 $crate::__spawn($body)
52 }};
53}
54
55#[macro_export]
86macro_rules! select {
87
88 ( recv($r:expr) -> $v:ident => $b:block $(,)? ) => {{
90 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
91 let mut __sel = ::std::vec![
92 $crate::select::recv_case_of(&($r), &mut __r0),
93 ];
94 let (_i, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
95 let $v: ::std::option::Option<_> = if __ok {
96 ::std::option::Option::Some(unsafe { __r0.assume_init() })
97 } else {
98 ::std::option::Option::None
99 };
100 $b
101 }};
102
103 ( recv($r:expr) -> $v:ident => $b:block $(,)? default => $d:block $(,)? ) => {{
105 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
106 let mut __sel = ::std::vec![
107 $crate::select::recv_case_of(&($r), &mut __r0),
108 ];
109 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
110 if __idx == 0 {
111 let $v: ::std::option::Option<_> = if __ok {
112 ::std::option::Option::Some(unsafe { __r0.assume_init() })
113 } else {
114 ::std::option::Option::None
115 };
116 $b
117 } else { $d }
118 }};
119
120 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
122 recv($r2:expr) -> $v2:ident => $b2:block $(,)? ) => {{
123 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
124 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
125 let mut __sel = ::std::vec![
126 $crate::select::recv_case_of(&($r1), &mut __r0),
127 $crate::select::recv_case_of(&($r2), &mut __r1),
128 ];
129 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
130 if __idx == 0 {
131 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
132 $b1
133 } else {
134 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
135 $b2
136 }
137 }};
138
139 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
141 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
142 default => $d:block $(,)? ) => {{
143 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
144 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
145 let mut __sel = ::std::vec![
146 $crate::select::recv_case_of(&($r1), &mut __r0),
147 $crate::select::recv_case_of(&($r2), &mut __r1),
148 ];
149 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
150 if __idx == 0 {
151 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
152 $b1
153 } else if __idx == 1 {
154 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
155 $b2
156 } else { $d }
157 }};
158
159 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
161 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
162 recv($r3:expr) -> $v3:ident => $b3:block $(,)? ) => {{
163 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
164 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
165 let mut __r2: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
166 let mut __sel = ::std::vec![
167 $crate::select::recv_case_of(&($r1), &mut __r0),
168 $crate::select::recv_case_of(&($r2), &mut __r1),
169 $crate::select::recv_case_of(&($r3), &mut __r2),
170 ];
171 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
172 if __idx == 0 {
173 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
174 $b1
175 } else if __idx == 1 {
176 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
177 $b2
178 } else {
179 let $v3: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r2.assume_init() }) } else { ::std::option::Option::None };
180 $b3
181 }
182 }};
183
184 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
186 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
187 recv($r3:expr) -> $v3:ident => $b3:block $(,)?
188 default => $d:block $(,)? ) => {{
189 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
190 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
191 let mut __r2: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
192 let mut __sel = ::std::vec![
193 $crate::select::recv_case_of(&($r1), &mut __r0),
194 $crate::select::recv_case_of(&($r2), &mut __r1),
195 $crate::select::recv_case_of(&($r3), &mut __r2),
196 ];
197 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
198 if __idx == 0 {
199 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
200 $b1
201 } else if __idx == 1 {
202 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
203 $b2
204 } else if __idx == 2 {
205 let $v3: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r2.assume_init() }) } else { ::std::option::Option::None };
206 $b3
207 } else { $d }
208 }};
209
210 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
212 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
213 recv($r3:expr) -> $v3:ident => $b3:block $(,)?
214 recv($r4:expr) -> $v4:ident => $b4:block $(,)? ) => {{
215 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
216 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
217 let mut __r2: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
218 let mut __r3: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
219 let mut __sel = ::std::vec![
220 $crate::select::recv_case_of(&($r1), &mut __r0),
221 $crate::select::recv_case_of(&($r2), &mut __r1),
222 $crate::select::recv_case_of(&($r3), &mut __r2),
223 $crate::select::recv_case_of(&($r4), &mut __r3),
224 ];
225 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
226 if __idx == 0 {
227 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
228 $b1
229 } else if __idx == 1 {
230 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
231 $b2
232 } else if __idx == 2 {
233 let $v3: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r2.assume_init() }) } else { ::std::option::Option::None };
234 $b3
235 } else {
236 let $v4: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r3.assume_init() }) } else { ::std::option::Option::None };
237 $b4
238 }
239 }};
240
241 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
243 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
244 recv($r3:expr) -> $v3:ident => $b3:block $(,)?
245 recv($r4:expr) -> $v4:ident => $b4:block $(,)?
246 default => $d:block $(,)? ) => {{
247 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
248 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
249 let mut __r2: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
250 let mut __r3: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
251 let mut __sel = ::std::vec![
252 $crate::select::recv_case_of(&($r1), &mut __r0),
253 $crate::select::recv_case_of(&($r2), &mut __r1),
254 $crate::select::recv_case_of(&($r3), &mut __r2),
255 $crate::select::recv_case_of(&($r4), &mut __r3),
256 ];
257 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
258 if __idx == 0 {
259 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
260 $b1
261 } else if __idx == 1 {
262 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
263 $b2
264 } else if __idx == 2 {
265 let $v3: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r2.assume_init() }) } else { ::std::option::Option::None };
266 $b3
267 } else if __idx == 3 {
268 let $v4: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r3.assume_init() }) } else { ::std::option::Option::None };
269 $b4
270 } else { $d }
271 }};
272
273 ( send($tx:expr, $sv:expr) => $sb:block $(,)? default => $d:block $(,)? ) => {{
275 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
276 let mut __sel = ::std::vec![
277 $crate::select::send_case_of(&($tx), &mut __s0),
278 ];
279 let (__idx, _ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
280 if __idx == 0 {
281 $sb
283 } else {
284 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
286 $d
287 }
288 }};
289
290 ( recv($r1:expr) -> $v1:ident => $rb:block $(,)?
292 send($tx:expr, $sv:expr) => $sb:block $(,)? ) => {{
293 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
294 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
295 let mut __sel = ::std::vec![
296 $crate::select::recv_case_of(&($r1), &mut __r0),
297 $crate::select::send_case_of(&($tx), &mut __s0),
298 ];
299 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
300 if __idx == 0 {
301 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
302 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
303 $rb
304 } else {
305 $sb
307 }
308 }};
309
310 ( recv($r1:expr) -> $v1:ident => $rb:block $(,)?
312 send($tx:expr, $sv:expr) => $sb:block $(,)?
313 default => $d:block $(,)? ) => {{
314 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
315 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
316 let mut __sel = ::std::vec![
317 $crate::select::recv_case_of(&($r1), &mut __r0),
318 $crate::select::send_case_of(&($tx), &mut __s0),
319 ];
320 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
321 if __idx == 0 {
322 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
323 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
324 $rb
325 } else if __idx == 1 {
326 $sb
327 } else {
328 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
329 $d
330 }
331 }};
332
333 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
335 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
336 send($tx:expr, $sv:expr) => $sb:block $(,)? ) => {{
337 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
338 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
339 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
340 let mut __sel = ::std::vec![
341 $crate::select::recv_case_of(&($r1), &mut __r0),
342 $crate::select::recv_case_of(&($r2), &mut __r1),
343 $crate::select::send_case_of(&($tx), &mut __s0),
344 ];
345 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
346 if __idx == 0 {
347 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
348 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
349 $b1
350 } else if __idx == 1 {
351 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
352 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
353 $b2
354 } else {
355 $sb
356 }
357 }};
358
359 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
361 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
362 send($tx:expr, $sv:expr) => $sb:block $(,)?
363 default => $d:block $(,)? ) => {{
364 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
365 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
366 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
367 let mut __sel = ::std::vec![
368 $crate::select::recv_case_of(&($r1), &mut __r0),
369 $crate::select::recv_case_of(&($r2), &mut __r1),
370 $crate::select::send_case_of(&($tx), &mut __s0),
371 ];
372 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
373 if __idx == 0 {
374 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
375 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
376 $b1
377 } else if __idx == 1 {
378 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
379 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
380 $b2
381 } else if __idx == 2 {
382 $sb
383 } else {
384 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
385 $d
386 }
387 }};
388
389 ( recv($r1:expr) -> $v1:ident => $b1:block $(,)?
391 recv($r2:expr) -> $v2:ident => $b2:block $(,)?
392 recv($r3:expr) -> $v3:ident => $b3:block $(,)?
393 send($tx:expr, $sv:expr) => $sb:block $(,)? ) => {{
394 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
395 let mut __r1: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
396 let mut __r2: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
397 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv);
398 let mut __sel = ::std::vec![
399 $crate::select::recv_case_of(&($r1), &mut __r0),
400 $crate::select::recv_case_of(&($r2), &mut __r1),
401 $crate::select::recv_case_of(&($r3), &mut __r2),
402 $crate::select::send_case_of(&($tx), &mut __s0),
403 ];
404 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
405 if __idx == 0 {
406 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
407 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
408 $b1
409 } else if __idx == 1 {
410 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
411 let $v2: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r1.assume_init() }) } else { ::std::option::Option::None };
412 $b2
413 } else if __idx == 2 {
414 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
415 let $v3: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r2.assume_init() }) } else { ::std::option::Option::None };
416 $b3
417 } else {
418 $sb
419 }
420 }};
421
422 ( recv($r1:expr) -> $v1:ident => $rb:block $(,)?
424 send($tx1:expr, $sv1:expr) => $sb1:block $(,)?
425 send($tx2:expr, $sv2:expr) => $sb2:block $(,)? ) => {{
426 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
427 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv1);
428 let mut __s1: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv2);
429 let mut __sel = ::std::vec![
430 $crate::select::recv_case_of(&($r1), &mut __r0),
431 $crate::select::send_case_of(&($tx1), &mut __s0),
432 $crate::select::send_case_of(&($tx2), &mut __s1),
433 ];
434 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, false) };
435 if __idx == 0 {
436 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0); ::std::mem::ManuallyDrop::drop(&mut __s1) };
437 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
438 $rb
439 } else if __idx == 1 {
440 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s1) };
442 $sb1
443 } else {
444 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
446 $sb2
447 }
448 }};
449
450 ( recv($r1:expr) -> $v1:ident => $rb:block $(,)?
452 send($tx1:expr, $sv1:expr) => $sb1:block $(,)?
453 send($tx2:expr, $sv2:expr) => $sb2:block $(,)?
454 default => $d:block $(,)? ) => {{
455 let mut __r0: ::std::mem::MaybeUninit<_> = ::std::mem::MaybeUninit::uninit();
456 let mut __s0: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv1);
457 let mut __s1: ::std::mem::ManuallyDrop<_> = ::std::mem::ManuallyDrop::new($sv2);
458 let mut __sel = ::std::vec![
459 $crate::select::recv_case_of(&($r1), &mut __r0),
460 $crate::select::send_case_of(&($tx1), &mut __s0),
461 $crate::select::send_case_of(&($tx2), &mut __s1),
462 ];
463 let (__idx, __ok) = unsafe { $crate::select::selectgo(&mut __sel, true) };
464 if __idx == 0 {
465 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0); ::std::mem::ManuallyDrop::drop(&mut __s1) };
466 let $v1: ::std::option::Option<_> = if __ok { ::std::option::Option::Some(unsafe { __r0.assume_init() }) } else { ::std::option::Option::None };
467 $rb
468 } else if __idx == 1 {
469 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s1) };
470 $sb1
471 } else if __idx == 2 {
472 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0) };
473 $sb2
474 } else {
475 unsafe { ::std::mem::ManuallyDrop::drop(&mut __s0); ::std::mem::ManuallyDrop::drop(&mut __s1) };
476 $d
477 }
478 }};
479}
480
481#[cfg(all(test, not(loom)))]
486#[allow(unused_assignments)] mod tests {
488 use crate::chan::chan;
489 use crate::runtime::sched::run_impl;
490 use std::sync::atomic::{AtomicI32, Ordering};
491 use std::sync::Arc;
492
493 #[test]
497 fn go_macro_spawns() {
498 let count = Arc::new(AtomicI32::new(0));
499 let c2 = Arc::clone(&count);
500 run_impl(move || {
501 go!(move || { c2.fetch_add(1, Ordering::Relaxed); });
502 for _ in 0..50 { crate::gosched(); }
504 });
505 assert_eq!(count.load(Ordering::Acquire), 1);
506 }
507
508 #[test]
512 fn select_recv_default_data_ready() {
513 run_impl(|| {
514 let (tx, rx) = chan::<i32>(1);
515 tx.send(7);
516 let mut got = -1_i32;
517 select! {
518 recv(rx) -> v => { got = v.unwrap(); }
519 default => { panic!("default should not fire"); }
520 }
521 assert_eq!(got, 7);
522 });
523 }
524
525 #[test]
527 fn select_default_when_empty() {
528 run_impl(|| {
529 let (_tx, rx) = chan::<i32>(1);
530 let mut took_default = false;
531 select! {
532 recv(rx) -> _v => { panic!("should not recv"); }
533 default => { took_default = true; }
534 }
535 assert!(took_default);
536 });
537 }
538
539 #[test]
541 fn select_two_recv_first_ready() {
542 run_impl(|| {
543 let (tx1, rx1) = chan::<i32>(1);
544 let (_tx2, rx2) = chan::<i32>(1);
545 tx1.send(42);
546 let mut winner = -1_i32;
547 select! {
548 recv(rx1) -> v => { winner = v.unwrap(); }
549 recv(rx2) -> _v => { panic!("rx2 should not fire"); }
550 default => {}
551 }
552 assert_eq!(winner, 42);
553 });
554 }
555
556 #[test]
558 fn select_send_default_space_available() {
559 run_impl(|| {
560 let (tx, rx) = chan::<i32>(1);
561 let mut sent = false;
562 select! {
563 send(tx, 99_i32) => { sent = true; }
564 default => { panic!("default should not fire"); }
565 }
566 assert!(sent);
567 assert_eq!(rx.recv(), Some(99));
568 });
569 }
570
571 #[test]
573 fn select_send_default_buffer_full() {
574 run_impl(|| {
575 let (tx, rx) = chan::<i32>(1);
576 tx.send(1); let mut took_default = false;
578 select! {
579 send(tx, 2_i32) => { panic!("should not send"); }
580 default => { took_default = true; }
581 }
582 assert!(took_default);
583 assert_eq!(rx.recv(), Some(1));
584 });
585 }
586
587 #[test]
590 fn select_recv_send_default() {
591 run_impl(|| {
592 let (tx1, rx1) = chan::<i32>(1);
593 let (tx2, rx2) = chan::<i32>(1);
594 tx1.send(10);
595 let mut recv_val = -1_i32;
596 let mut send_ok = false;
597 select! {
599 recv(rx1) -> v => { recv_val = v.unwrap(); }
600 send(tx2, 20_i32) => { send_ok = true; }
601 default => {}
602 }
603 assert!(recv_val == 10 || send_ok);
605 let _ = rx2.try_recv(); });
607 }
608
609 #[test]
613 fn select_blocking_recv() {
614 let result = Arc::new(AtomicI32::new(-1));
615 let r2 = Arc::clone(&result);
616 run_impl(move || {
617 let (tx, rx) = chan::<i32>(0);
618 go!(move || { tx.send(55); });
619 select! {
620 recv(rx) -> v => { r2.store(v.unwrap(), Ordering::Relaxed); }
621 }
622 });
623 assert_eq!(result.load(Ordering::Acquire), 55);
624 }
625
626 #[test]
628 fn select_blocking_two_recv() {
629 let winner = Arc::new(AtomicI32::new(-1));
630 let w2 = Arc::clone(&winner);
631 run_impl(move || {
632 let (tx1, rx1) = chan::<i32>(0);
633 let (tx2, rx2) = chan::<i32>(0);
634 go!(move || { tx1.send(1); });
635 go!(move || { tx2.send(2); });
636 select! {
637 recv(rx1) -> v => { w2.store(v.unwrap(), Ordering::Relaxed); }
638 recv(rx2) -> v => { w2.store(v.unwrap(), Ordering::Relaxed); }
639 }
640 });
641 let w = winner.load(Ordering::Acquire);
642 assert!(w == 1 || w == 2, "winner should be 1 or 2, got {w}");
643 }
644
645 #[test]
647 fn select_blocking_recv_send() {
648 let recv_val = Arc::new(AtomicI32::new(-1));
649 let rv2 = Arc::clone(&recv_val);
650 run_impl(move || {
651 let (tx1, rx1) = chan::<i32>(0); let (tx2, rx2) = chan::<i32>(0); go!(move || { tx1.send(77); });
655 go!(move || {
657 crate::gosched();
659 let _ = rx2.recv();
660 });
661 select! {
662 recv(rx1) -> v => { rv2.store(v.unwrap(), Ordering::Relaxed); }
663 send(tx2, 99_i32) => {}
664 }
665 });
666 let v = recv_val.load(Ordering::Acquire);
668 assert!(v == 77 || v == -1, "unexpected value {v}");
669 }
670
671 #[test]
673 fn select_recv_closed_yields_none() {
674 run_impl(|| {
675 let (tx, rx) = chan::<i32>(0);
676 tx.close();
677 let mut ok_flag = true;
678 select! {
679 recv(rx) -> v => { ok_flag = v.is_some(); }
680 }
681 assert!(!ok_flag, "should be None for closed channel");
682 });
683 }
684}