Atomic for &str/String

I am trying to use Rocket to build a server that has certain state shareable between endpoints.
So ideally, I should use state. Problem is some of the state involves String, like for example, I read a token from a json file:

#[derive(Debug)]
pub struct SaveData {
    pub token: AtomicPtr<&'static str>,
}

impl SaveData {
    pub fn new() -> Result<SaveData>{


        let path = "./temporary/save_data.json";
        let file = File::open(path)?;
        let reader = BufReader::new(file);

        let u:SaveDataJson = serde_json::from_reader(reader)?;

        let mut token_string = u.token;
        let token_ptr = AtomicPtr::new(token_string.as_mut_ptr() as *mut &str);
        let sd = SaveData{ token: token_ptr };
        Ok(sd)
    }

    pub fn get_token(&self) -> String {
        let mstr = self.token.load(Ordering::Relaxed);
        let str = unsafe {*mstr};
        str.to_string()
    }


    pub fn set_token(&self, mut new_token: String)  {
        self.token.store(new_token.as_mut_ptr() as *mut &str, Ordering::Relaxed)
    }
}

Yeah does not work. I got STATUS_STACK_BUFFER_OVERRUN on get_token.
So how to do Atomic for String? (Or if needs to be more percise, how to share state involving a String in Rocket?)
Thank you.
Also, does it matter if I use Ordering::Relaxed versus something like Ordering::AcqRel or Ordering::SeqCst

If this cast is needed to compile (can't be sure without seeing the definition of SaveDataJson) then this is likely wrong because you're casting a pointer to the string content to a pointer to a pointer to string content.

Use a Mutex/RwLock instead. AtomicPtr is like a raw pointer, thus for unsafe manipulations, and you shouldn't use it if you aren't 100% sure of what you're doing.

6 Likes

This is the solution. @SkiFire13 answer lead me to this.

#[derive(Debug)]
pub struct SaveData {
    pub token: Arc<Mutex<String>>
}

//...

impl SaveData {
   
    pub fn get_token(&self) -> String {
        let token = self.token.lock().unwrap();
        token.to_string()
    }


    pub fn set_token(&self, mut new_token: String)  {
        let mut token = self.token.lock().unwrap();
        *token = new_token
    }
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.