@@ -57,10 +57,10 @@ impl<const SIZE: usize> EfiVariableBuffer<SIZE> {
5757 }
5858}
5959
60- impl < const SIZE : usize > TryFrom < & mut dyn Read > for EfiVariableBuffer < SIZE > {
60+ impl < const SIZE : usize > TryFrom < File > for EfiVariableBuffer < SIZE > {
6161 type Error = Box < dyn Error > ;
6262
63- fn try_from ( handle : & mut dyn Read ) -> Result < Self , Self :: Error > {
63+ fn try_from ( mut handle : File ) -> Result < Self , Self :: Error > {
6464 let mut buffer = Self :: new ( ) ;
6565 let total_buffer_size = match SIZE {
6666 8 => Ok ( 2084 ) , // cannot use size_of with EfiVariableBuffer<SIZE>
@@ -209,9 +209,9 @@ impl EfiVariables {
209209 . path
210210 . join ( String :: new ( ) + prefix + & "-" + format ! ( "{}" , guid) . as_str ( ) )
211211 . join ( "raw_var" ) ;
212- let mut handle = File :: open ( efi_variable_path) ?;
212+ let handle = File :: open ( efi_variable_path) ?;
213213
214- let efi_variable = self . parse_payload ( & mut handle) ?;
214+ let efi_variable = self . parse_payload ( handle) ?;
215215 if * efi_variable. name != * prefix {
216216 return Err :: < EfiVariable , Box < dyn Error > > (
217217 "Corrupt variable. Reported name does not match name" . into ( ) ,
@@ -225,7 +225,7 @@ impl EfiVariables {
225225 return Ok ( efi_variable) ;
226226 }
227227
228- fn parse_payload ( & self , reader : & mut dyn Read ) -> Result < EfiVariable , Box < dyn Error > > {
228+ fn parse_payload ( & self , reader : File ) -> Result < EfiVariable , Box < dyn Error > > {
229229 let mut buffer: Box < dyn EfiNVariableBuffer > = match self . platform_size {
230230 64 => {
231231 Ok ( Box :: new ( Efi64VariableBuffer :: try_from ( reader) ?) as Box < dyn EfiNVariableBuffer > )
@@ -319,56 +319,52 @@ impl EfiVariables {
319319#[ cfg( test) ]
320320mod tests {
321321 use super :: * ;
322+ use std:: cell:: RefCell ;
322323 use std:: cmp:: min;
323324 use std:: collections:: VecDeque ;
324325 use std:: io:: { Read , Write } ;
325- use std:: sync:: Mutex ;
326326
327- static BUFFER_MOCK : Mutex < VecDeque < u8 > > = Mutex :: new ( VecDeque :: new ( ) ) ;
328- static RUNNER_LOCK : Mutex < u8 > = Mutex :: new ( 0xff ) ;
329-
330- pub struct File < ' a > {
331- buffer : & ' a Mutex < VecDeque < u8 > > ,
327+ thread_local ! {
328+ static STRIO_BUFFER : RefCell <VecDeque <u8 >> = RefCell :: new( VecDeque :: new( ) ) ;
332329 }
333330
334- impl File < ' _ > {
331+ pub struct File { }
332+
333+ impl File {
335334 pub fn open < P : AsRef < Path > > ( _path : P ) -> std:: io:: Result < Self > {
336- return Ok ( Self {
337- buffer : & BUFFER_MOCK ,
338- } ) ;
335+ return Ok ( File { } ) ;
339336 }
340337 }
341338
342- impl Read for File < ' _ > {
339+ impl Read for File {
343340 fn read ( & mut self , dst : & mut [ u8 ] ) -> std:: io:: Result < usize > {
344- return self . buffer . lock ( ) . unwrap ( ) . read ( dst) ;
341+ return STRIO_BUFFER . with ( |b| {
342+ return ( * b) . borrow_mut ( ) . read ( dst) ;
343+ } ) ;
345344 }
346345
347346 fn read_vectored ( & mut self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> std:: io:: Result < usize > {
348- let mut inner_buffer = self . buffer . lock ( ) . unwrap ( ) ;
349347 let mut total_bytes_read: usize = 0 ;
350- bufs. iter_mut ( ) . filter ( |b| !b. is_empty ( ) ) . for_each ( |b| {
351- let bytes_read = min ( b. len ( ) , inner_buffer. len ( ) ) ;
352- b[ ..bytes_read] . copy_from_slice (
353- & inner_buffer
354- . drain ( ..bytes_read)
355- . collect :: < Vec < u8 > > ( )
356- . as_slice ( ) ,
357- ) ;
358- total_bytes_read += bytes_read;
348+ STRIO_BUFFER . with ( |tl_b| {
349+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
350+ bufs. iter_mut ( ) . filter ( |db| !db. is_empty ( ) ) . for_each ( |db| {
351+ let bytes_read = min ( db. len ( ) , sb. len ( ) ) ;
352+ db[ ..bytes_read]
353+ . copy_from_slice ( sb. drain ( ..bytes_read) . collect :: < Vec < u8 > > ( ) . as_slice ( ) ) ;
354+ total_bytes_read += bytes_read;
355+ } ) ;
359356 } ) ;
360-
361357 return Ok ( total_bytes_read) ;
362358 }
363359 }
364360
365361 #[ test]
366362 fn get_firmware_platform_size ( ) {
367- let _lock = RUNNER_LOCK . lock ( ) ;
368363 {
369- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
370- mock_buffer. clear ( ) ;
371- mock_buffer. write ( "32\n " . as_bytes ( ) ) . unwrap ( ) ;
364+ STRIO_BUFFER . with ( |tl_b| {
365+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
366+ sb. write ( "32\n " . as_bytes ( ) ) . unwrap ( ) ;
367+ } ) ;
372368 }
373369 assert_eq ! (
374370 EfiVariables :: get_firmware_platform_size( & PathBuf :: from( "/tmp/unit_test_refivar" ) )
@@ -377,9 +373,10 @@ mod tests {
377373 ) ;
378374
379375 {
380- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
381- mock_buffer. clear ( ) ;
382- mock_buffer. write ( "64\n " . as_bytes ( ) ) . unwrap ( ) ;
376+ STRIO_BUFFER . with ( |tl_b| {
377+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
378+ sb. write ( "64\n " . as_bytes ( ) ) . unwrap ( ) ;
379+ } ) ;
383380 }
384381 assert_eq ! (
385382 EfiVariables :: get_firmware_platform_size( & PathBuf :: from( "/tmp/unit_test_refivar" ) )
@@ -388,9 +385,10 @@ mod tests {
388385 ) ;
389386
390387 {
391- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
392- mock_buffer. clear ( ) ;
393- mock_buffer. write ( "1\n " . as_bytes ( ) ) . unwrap ( ) ;
388+ STRIO_BUFFER . with ( |tl_b| {
389+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
390+ sb. write ( "1\n " . as_bytes ( ) ) . unwrap ( ) ;
391+ } ) ;
394392 }
395393 assert_eq ! (
396394 EfiVariables :: get_firmware_platform_size( & PathBuf :: from( "/tmp/unit_test_refivar" ) )
@@ -421,14 +419,8 @@ mod tests {
421419
422420 #[ test]
423421 fn efi_variable_buffer_32_read_empty ( ) {
424- let _lock = RUNNER_LOCK . lock ( ) ;
425- {
426- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
427- mock_buffer. clear ( ) ;
428- }
429- let var = Efi32VariableBuffer :: try_from (
430- BUFFER_MOCK . lock ( ) . as_deref_mut ( ) . unwrap ( ) as & mut dyn Read
431- ) ;
422+ let file = File { } ;
423+ let var = Efi32VariableBuffer :: try_from ( file) ;
432424
433425 assert_eq ! (
434426 ( * var. err( ) . unwrap( ) ) . to_string( ) ,
@@ -438,15 +430,14 @@ mod tests {
438430
439431 #[ test]
440432 fn efi_variable_buffer_32_read_short ( ) {
441- let _lock = RUNNER_LOCK . lock ( ) ;
442433 {
443- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
444- mock_buffer. clear ( ) ;
445- mock_buffer. write ( "1" . as_bytes ( ) ) . unwrap ( ) ;
434+ STRIO_BUFFER . with ( |tl_b| {
435+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
436+ sb. write ( "1" . as_bytes ( ) ) . unwrap ( ) ;
437+ } ) ;
446438 }
447- let var = Efi32VariableBuffer :: try_from (
448- BUFFER_MOCK . lock ( ) . as_deref_mut ( ) . unwrap ( ) as & mut dyn Read
449- ) ;
439+ let file = File { } ;
440+ let var = Efi32VariableBuffer :: try_from ( file) ;
450441
451442 assert_eq ! (
452443 ( * var. err( ) . unwrap( ) ) . to_string( ) ,
@@ -456,16 +447,14 @@ mod tests {
456447
457448 #[ test]
458449 fn efi_variable_buffer_32_read_too_long ( ) {
459- let _lock = RUNNER_LOCK . lock ( ) ;
460450 {
461- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
462- mock_buffer. clear ( ) ;
463- mock_buffer. write ( & [ 0xff ; 2077 ] ) . unwrap ( ) ;
451+ STRIO_BUFFER . with ( |tl_b| {
452+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
453+ sb. write ( & [ 0xff ; 2077 ] ) . unwrap ( ) ;
454+ } ) ;
464455 }
465- let mut mock_stream = File {
466- buffer : & BUFFER_MOCK ,
467- } ;
468- let var = Efi32VariableBuffer :: try_from ( & mut mock_stream as & mut dyn Read ) ;
456+ let file = File { } ;
457+ let var = Efi32VariableBuffer :: try_from ( file) ;
469458
470459 assert_eq ! (
471460 ( * var. err( ) . unwrap( ) ) . to_string( ) ,
@@ -475,15 +464,14 @@ mod tests {
475464
476465 #[ test]
477466 fn efi_variable_buffer_64_read_short ( ) {
478- let _lock = RUNNER_LOCK . lock ( ) ;
479467 {
480- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
481- mock_buffer. clear ( ) ;
482- mock_buffer. write ( "1" . as_bytes ( ) ) . unwrap ( ) ;
468+ STRIO_BUFFER . with ( |tl_b| {
469+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
470+ sb. write ( "1" . as_bytes ( ) ) . unwrap ( ) ;
471+ } ) ;
483472 }
484- let var = Efi64VariableBuffer :: try_from (
485- BUFFER_MOCK . lock ( ) . as_deref_mut ( ) . unwrap ( ) as & mut dyn Read
486- ) ;
473+ let file = File { } ;
474+ let var = Efi64VariableBuffer :: try_from ( file) ;
487475
488476 assert_eq ! (
489477 ( * var. err( ) . unwrap( ) ) . to_string( ) ,
@@ -493,16 +481,14 @@ mod tests {
493481
494482 #[ test]
495483 fn efi_variable_buffer_64_read_too_long ( ) {
496- let _lock = RUNNER_LOCK . lock ( ) ;
497484 {
498- let mut mock_buffer = BUFFER_MOCK . lock ( ) . unwrap ( ) ;
499- mock_buffer. clear ( ) ;
500- mock_buffer. write ( & [ 0xff ; 2085 ] ) . unwrap ( ) ;
485+ STRIO_BUFFER . with ( |tl_b| {
486+ let mut sb = ( * tl_b) . borrow_mut ( ) ;
487+ sb. write ( & [ 0xff ; 2085 ] ) . unwrap ( ) ;
488+ } ) ;
501489 }
502- let mut mock_stream = File {
503- buffer : & BUFFER_MOCK ,
504- } ;
505- let var = Efi64VariableBuffer :: try_from ( & mut mock_stream as & mut dyn Read ) ;
490+ let file = File { } ;
491+ let var = Efi64VariableBuffer :: try_from ( file) ;
506492
507493 assert_eq ! (
508494 ( * var. err( ) . unwrap( ) ) . to_string( ) ,
0 commit comments