罗旭皓
罗旭皓

Reputation: 91

Use spin lock and lazy_static! on a static struct

I was trying to create a mutable struct (an interrupt descriptor table) with s static lifetime. Since the static mut is not safe, I use an alternative of lazy_static and mutex like this

use lazy_static::lazy_static;
use spin::Mutex;

lazy_static! {
    pub static ref IDT: Mutex<idt_type> = Mutex::new(...);
}

My 'idt_type' has a method which takes a static self as perameter like this:

impl idt_type {
    pub fn load(&'static self);
}

However is I try to use this method like this

IDT.lock().load();

the complier will complain since lock() returns a non static MutexGuard:

         IDT.lock().load();
   |     ^^^^^^^^^^-------- temporary value is freed at the end of this statement
   |     |
   |     creates a temporary which is freed while still in use
   |     argument requires that borrow lasts for `'static`

Is there any way to work around?

Upvotes: 0

Views: 626

Answers (1)

edwardw
edwardw

Reputation: 13942

Judging from the abridged code you showed here, moving Mutex inside the IDT type will do the job:

use lazy_static::lazy_static;
use spin::Mutex;

lazy_static! {
    pub static ref IDT: IdtType = IdtType(Mutex::new(0));
}

pub struct IdtType(Mutex<i32>);

impl IdtType {
    pub fn load(&'static self) {
        self.0.lock();
    }
}

fn main() {
    IDT.load();
}

It is now your responsibility to implement the locking logic correctly instead of users of your crate. So it also has the added benefit of reducing the chance of misusing the API.

Upvotes: 4

Related Questions