@@ -346,11 +346,20 @@ unsafe fn enqueue<T>(
346
346
mod tests {
347
347
use static_assertions:: assert_not_impl_any;
348
348
349
- use super :: Queue ;
349
+ use super :: { Queue , QueueView } ;
350
350
351
351
// Ensure a `Queue` containing `!Send` values stays `!Send` itself.
352
352
assert_not_impl_any ! ( Queue <* const ( ) , 4 >: Send ) ;
353
353
354
+ fn to_vec < T > ( q : & QueueView < T > ) -> Vec < T > {
355
+ // inaccurate
356
+ let mut ret = vec ! [ ] ;
357
+ while let Some ( v) = q. dequeue ( ) {
358
+ ret. push ( v) ;
359
+ }
360
+ ret
361
+ }
362
+
354
363
#[ test]
355
364
fn memory_leak ( ) {
356
365
droppable ! ( ) ;
@@ -419,4 +428,83 @@ mod tests {
419
428
// Queue is full, this should not block forever.
420
429
q. enqueue ( 0x55 ) . unwrap_err ( ) ;
421
430
}
431
+
432
+ #[ test]
433
+ fn issue_583_enqueue ( ) {
434
+ const N : usize = 4 ;
435
+
436
+ let q0 = Queue :: < u8 , N > :: new ( ) ;
437
+ for i in 0 ..N {
438
+ q0. enqueue ( i as u8 ) . expect ( "new enqueue" ) ;
439
+ }
440
+ eprintln ! ( "start!" ) ;
441
+
442
+ std:: thread:: scope ( |sc| {
443
+ for _ in 0 ..2 {
444
+ sc. spawn ( || {
445
+ for k in 0 ..1000_000 {
446
+ if let Some ( v) = q0. dequeue ( ) {
447
+ q0. enqueue ( v) . unwrap_or_else ( |v| {
448
+ panic ! ( "{k}: q0 -> q0: {v}, {:?}" , to_vec( & q0) )
449
+ } ) ;
450
+ }
451
+ }
452
+ } ) ;
453
+ }
454
+ } ) ;
455
+ }
456
+
457
+ #[ test]
458
+ fn issue_583_dequeue ( ) {
459
+ const N : usize = 4 ;
460
+
461
+ let q0 = Queue :: < u8 , N > :: new ( ) ;
462
+ eprintln ! ( "start!" ) ;
463
+ std:: thread:: scope ( |sc| {
464
+ for _ in 0 ..2 {
465
+ sc. spawn ( || {
466
+ for k in 0 ..1000_000 {
467
+ q0. enqueue ( k as u8 ) . unwrap ( ) ;
468
+ if q0. dequeue ( ) . is_none ( ) {
469
+ panic ! ( "{k}" ) ;
470
+ }
471
+ }
472
+ } ) ;
473
+ }
474
+ } ) ;
475
+ }
476
+
477
+ #[ test]
478
+ fn issue_583_enqueue_loom ( ) {
479
+ const N : usize = 4 ;
480
+
481
+ loom:: model ( || {
482
+ let q0 = loom:: sync:: Arc :: new ( Queue :: < u8 , N > :: new ( ) ) ;
483
+ for i in 0 ..N {
484
+ q0. enqueue ( i as u8 ) . expect ( "new enqueue" ) ;
485
+ }
486
+ eprintln ! ( "start!" ) ;
487
+
488
+ let q1 = q0. clone ( ) ;
489
+ loom:: thread:: spawn ( move || {
490
+ for k in 0 ..1000_000 {
491
+ if let Some ( v) = q0. dequeue ( ) {
492
+ q0. enqueue ( v) . unwrap_or_else ( |v| {
493
+ panic ! ( "{k}: q0 -> q0: {v}, {:?}" , to_vec( & * q0) )
494
+ } ) ;
495
+ }
496
+ }
497
+ } ) ;
498
+
499
+ loom:: thread:: spawn ( move || {
500
+ for k in 0 ..1000_000 {
501
+ if let Some ( v) = q1. dequeue ( ) {
502
+ q1. enqueue ( v) . unwrap_or_else ( |v| {
503
+ panic ! ( "{k}: q0 -> q0: {v}, {:?}" , to_vec( & * q1) )
504
+ } ) ;
505
+ }
506
+ }
507
+ } ) ;
508
+ } ) ;
509
+ }
422
510
}
0 commit comments