@@ -308,29 +308,55 @@ impl EventHandler for Serial {
308
308
mod tests {
309
309
use super :: * ;
310
310
use std:: io;
311
+ use std:: io:: Write ;
312
+ use std:: os:: unix:: io:: RawFd ;
311
313
use std:: sync:: { Arc , Mutex } ;
312
314
315
+ use polly:: event_manager:: EventManager ;
316
+
317
+ struct SharedBufferInternal {
318
+ read_buf : Vec < u8 > ,
319
+ write_buf : Vec < u8 > ,
320
+ evfd : EventFd ,
321
+ }
322
+
313
323
#[ derive( Clone ) ]
314
324
struct SharedBuffer {
315
- buf : Arc < Mutex < Vec < u8 > > > ,
325
+ internal : Arc < Mutex < SharedBufferInternal > > ,
316
326
}
317
327
318
328
impl SharedBuffer {
319
329
fn new ( ) -> SharedBuffer {
320
330
SharedBuffer {
321
- buf : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
331
+ internal : Arc :: new ( Mutex :: new ( SharedBufferInternal {
332
+ read_buf : Vec :: new ( ) ,
333
+ write_buf : Vec :: new ( ) ,
334
+ evfd : EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ,
335
+ } ) ) ,
322
336
}
323
337
}
324
338
}
325
-
326
339
impl io:: Write for SharedBuffer {
327
340
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
328
- self . buf . lock ( ) . unwrap ( ) . write ( buf)
341
+ self . internal . lock ( ) . unwrap ( ) . write_buf . write ( buf)
329
342
}
330
343
fn flush ( & mut self ) -> io:: Result < ( ) > {
331
- self . buf . lock ( ) . unwrap ( ) . flush ( )
344
+ self . internal . lock ( ) . unwrap ( ) . write_buf . flush ( )
345
+ }
346
+ }
347
+ impl io:: Read for SharedBuffer {
348
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
349
+ self . internal . lock ( ) . unwrap ( ) . read_buf . as_slice ( ) . read ( buf)
332
350
}
333
351
}
352
+ impl AsRawFd for SharedBuffer {
353
+ fn as_raw_fd ( & self ) -> RawFd {
354
+ self . internal . lock ( ) . unwrap ( ) . evfd . as_raw_fd ( )
355
+ }
356
+ }
357
+ impl ReadableFd for SharedBuffer { }
358
+
359
+ static RAW_INPUT_BUF : [ u8 ; 3 ] = [ b'a' , b'b' , b'c' ] ;
334
360
335
361
#[ test]
336
362
fn serial_output ( ) {
@@ -339,52 +365,100 @@ mod tests {
339
365
340
366
let mut serial = Serial :: new_out ( intr_evt, Box :: new ( serial_out. clone ( ) ) ) ;
341
367
368
+ // Invalid write of multiple chars at once.
342
369
serial. write ( u64:: from ( DATA ) , & [ b'x' , b'y' ] ) ;
343
- serial. write ( u64:: from ( DATA ) , & [ b'a' ] ) ;
344
- serial. write ( u64:: from ( DATA ) , & [ b'b' ] ) ;
345
- serial. write ( u64:: from ( DATA ) , & [ b'c' ] ) ;
370
+ // Valid one char at a time writes.
371
+ RAW_INPUT_BUF
372
+ . iter ( )
373
+ . for_each ( |& c| serial. write ( u64:: from ( DATA ) , & [ c] ) ) ;
346
374
assert_eq ! (
347
- serial_out. buf . lock( ) . unwrap( ) . as_slice( ) ,
348
- & [ b'a' , b'b' , b'c' ]
375
+ serial_out. internal . lock( ) . unwrap( ) . write_buf . as_slice( ) ,
376
+ & RAW_INPUT_BUF
349
377
) ;
350
378
}
351
379
352
380
#[ test]
353
- fn serial_input ( ) {
381
+ fn serial_raw_input ( ) {
354
382
let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
355
383
let serial_out = SharedBuffer :: new ( ) ;
356
384
357
- let mut serial =
358
- Serial :: new_out ( intr_evt. try_clone ( ) . unwrap ( ) , Box :: new ( serial_out. clone ( ) ) ) ;
385
+ let mut serial = Serial :: new_out ( intr_evt. try_clone ( ) . unwrap ( ) , Box :: new ( serial_out) ) ;
359
386
360
- // write 1 to the interrupt event fd, so that read doesn't block in case the event fd
361
- // counter doesn't change (for 0 it blocks)
387
+ // Write 1 to the interrupt event fd, so that read doesn't block in case the event fd
388
+ // counter doesn't change (for 0 it blocks).
362
389
assert ! ( intr_evt. write( 1 ) . is_ok( ) ) ;
363
390
serial. write ( u64:: from ( IER ) , & [ IER_RECV_BIT ] ) ;
364
- serial. raw_input ( & [ b'a' , b'b' , b'c' ] ) . unwrap ( ) ;
391
+ serial. raw_input ( & RAW_INPUT_BUF ) . unwrap ( ) ;
365
392
393
+ // Verify the serial raised an interrupt.
366
394
assert_eq ! ( intr_evt. read( ) . unwrap( ) , 2 ) ;
367
395
368
- // check if reading in a 2-length array doesn't have side effects
396
+ // Check if reading in a 2-length array doesn't have side effects.
369
397
let mut data = [ 0u8 , 0u8 ] ;
370
398
serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
371
399
assert_eq ! ( data, [ 0u8 , 0u8 ] ) ;
372
400
373
401
let mut data = [ 0u8 ] ;
374
402
serial. read ( u64:: from ( LSR ) , & mut data[ ..] ) ;
375
403
assert_ne ! ( data[ 0 ] & LSR_DATA_BIT , 0 ) ;
376
- serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
377
- assert_eq ! ( data[ 0 ] , b'a' ) ;
378
- serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
379
- assert_eq ! ( data[ 0 ] , b'b' ) ;
380
- serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
381
- assert_eq ! ( data[ 0 ] , b'c' ) ;
382
404
383
- // check if reading from the largest u8 offset returns 0
405
+ // Verify reading the previously inputted buffer.
406
+ RAW_INPUT_BUF . iter ( ) . for_each ( |& c| {
407
+ serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
408
+ assert_eq ! ( data[ 0 ] , c) ;
409
+ } ) ;
410
+
411
+ // Check if reading from the largest u8 offset returns 0.
384
412
serial. read ( 0xff , & mut data[ ..] ) ;
385
413
assert_eq ! ( data[ 0 ] , 0 ) ;
386
414
}
387
415
416
+ #[ test]
417
+ fn serial_input ( ) {
418
+ let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
419
+ let serial_in_out = SharedBuffer :: new ( ) ;
420
+
421
+ let mut serial = Serial :: new_in_out (
422
+ intr_evt. try_clone ( ) . unwrap ( ) ,
423
+ Box :: new ( serial_in_out. clone ( ) ) ,
424
+ Box :: new ( serial_in_out. clone ( ) ) ,
425
+ ) ;
426
+
427
+ // Write 1 to the interrupt event fd, so that read doesn't block in case the event fd
428
+ // counter doesn't change (for 0 it blocks).
429
+ assert ! ( intr_evt. write( 1 ) . is_ok( ) ) ;
430
+ serial. write ( u64:: from ( IER ) , & [ IER_RECV_BIT ] ) ;
431
+
432
+ // Prepare the input buffer.
433
+ {
434
+ let mut guard = serial_in_out. internal . lock ( ) . unwrap ( ) ;
435
+ guard. read_buf . write_all ( & RAW_INPUT_BUF ) . unwrap ( ) ;
436
+ guard. evfd . write ( 1 ) . unwrap ( ) ;
437
+ }
438
+
439
+ let mut evmgr = EventManager :: new ( ) . unwrap ( ) ;
440
+ let serial_wrap = EventManager :: wrap_handler ( serial) ;
441
+ evmgr. register ( serial_wrap. clone ( ) ) . unwrap ( ) ;
442
+
443
+ // Run the event handler which should drive serial input.
444
+ // There should be one event reported (which should have also handled serial input).
445
+ assert_eq ! ( evmgr. run_timeout( 50 ) . unwrap( ) , 1 ) ;
446
+
447
+ // Verify the serial raised an interrupt.
448
+ assert_eq ! ( intr_evt. read( ) . unwrap( ) , 2 ) ;
449
+
450
+ let mut serial = serial_wrap. lock ( ) . unwrap ( ) ;
451
+ let mut data = [ 0u8 ] ;
452
+ serial. read ( u64:: from ( LSR ) , & mut data[ ..] ) ;
453
+ assert_ne ! ( data[ 0 ] & LSR_DATA_BIT , 0 ) ;
454
+
455
+ // Verify reading the previously inputted buffer.
456
+ RAW_INPUT_BUF . iter ( ) . for_each ( |& c| {
457
+ serial. read ( u64:: from ( DATA ) , & mut data[ ..] ) ;
458
+ assert_eq ! ( data[ 0 ] , c) ;
459
+ } ) ;
460
+ }
461
+
388
462
#[ test]
389
463
fn serial_thr ( ) {
390
464
let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
0 commit comments