Skip to content

Commit 69cca36

Browse files
committed
use thread local variables instead of globals
use thread local variables instead of globals for testing.
1 parent b7ad22a commit 69cca36

File tree

1 file changed

+62
-76
lines changed

1 file changed

+62
-76
lines changed

src/lib/efivar/efivar/efi_variables.rs

Lines changed: 62 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
320320
mod 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

Comments
 (0)