DashMap can easily get stuck

use dashmap::DashMap;

pub struct Student
{
    pub name:String,
    pub age:i32,
}

pub struct Teacher
{
    pub name:String,
    pub age:i32,
}

pub trait Person: Send + Sync {
    fn getName(&mut self)->String{
        todo!()
	}

    fn setName(&mut self, name:String){
		todo!()
	}
}

impl Person for Student {
    fn getName(&mut self)->String{
		self.name.clone()
	}

    fn setName(&mut self, name:String){
		self.name = name;
	}
}

impl Person for Teacher {
    fn getName(&mut self)->String{
		self.name.clone()
	}

    fn setName(&mut self, name:String){
		self.name = name;
	}

}

#[tokio::main]
async fn main() -> Result<(), IoError>{


    let mut mapData:DashMap<String, Arc<dyn Person + Send + Sync>> = DashMap::new();
    mapData.insert(format!("oneKey"), Arc::new(Student { name:format!("peter"), age: 18 }));
    mapData.insert(format!("twoKey"), Arc::new(Student { name:format!("yohan"), age: 19 }));
    mapData.insert(format!("threeKey"), Arc::new(Teacher { name:format!("kale"), age: 22 }));
    mapData.insert(format!("fourKey"), Arc::new(Teacher { name:format!("peHone"), age: 21 }));

    tokio::spawn(async move {
        loop {
            
            for i in 0..4  {

                let mut personName0 = format!("threeKey");
                let mut personName1 = format!("oneKey");

                let mut person0 = mapData.get_mut(&personName0);
                let mut personValue0 = Arc::get_mut(person0.as_mut().unwrap().value_mut()).unwrap();
                println!("personName0:{}", personValue0.getName());
    
                let mut person1 = mapData.get_mut(&personName1);
                let mut personValue1 = Arc::get_mut(person1.as_mut().unwrap().value_mut()).unwrap();
                println!("personName1:{}", personValue1.getName());
    
            }


            time::sleep(time::Duration::from_millis(20)).await;
        }
    });

   
    // Ok(())
}

After running for a period of time, it is easy to get stuck here

                let mut person0 = mapData.get_mut(&personName0);

From the documentation of DashMap::get_mut:

Locking behaviour: May deadlock if called when holding any sort of reference into the map.

You are calling mapData.get_mut(&personName1) while person0, a reference into the map, is alive. Consider dropping person0 (for example drop(person0) before calling get_mut to get person1.

7 Likes

Thank you

Since you had a question and got an answer, I suggest adding the Help category (edit the title at the top to do this) and then select @SkiFire13 's post as the answer. That makes it easier for others searching for an answer to a similar question, and also those looking to see if this conversation was resolved. If you look at other Help posts on this forum you can see examples of this being done.

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.