You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.6 KiB

drop_the_thread

Instructions

"Interior mutability is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data"

in this exercise a Drop checker API has to be created. For this you must define:

  • Two structures:

    • Workers that will have two fields:
      • drops that will save the number of dropped threads.
      • states that will save a state of multiple threads. If the thread is not dropped, the state will be false otherwise true.
    • Thread that will have the following fields:
      • pid, the id of the thread.
      • cmd, the name of the thread.
      • parent, that will be the link to the structure Workers (Tip: this must be a reference to the structure Workers)
  • Implementation of each structure:

    • Workers :

      • new, that creates a default worker
      • new_worker, that returns a tuple with the pid and a new Thread, this function must receive a String being the cmd
        • is_dropped, that receives a pid and returns a bool that indicates the state of the thread by using the pid
        • track_worker, it should return a usize, that will be the last available index of the states vector, being the new next thread
      • add_drop, this function must be called by the Drop trait. It will receive a pid that will be used to change the state of the thread. If the state of that thread is true then it will panic with the message ("Cannot drop {}, because its already dropped", pid). Otherwise it should change the state to true and increment the drops field by one.
    • Thread:

      • new_thread, that initializes a new thread
      • skill, that drops the thread
  • You must implement for the structure Thread the Drop trait. In this trait you must call the function add_drop so that the state of the thread changes

Notions

Expected Functions

use std::cell::{RefCell, Cell};

#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct Workers {
    pub drops: Cell<usize>,
    pub state: RefCell<Vec<bool>>
}

impl Workers {
    pub fn new() -> Workers {}
    pub fn new_worker(&self, c: String) -> (usize, Thread) {}
    pub fn track_worker(&self) -> usize {}
    pub fn is_dropped(&self, id: usize) -> bool {}
    pub fn add_drop(&self, id: usize) {}
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Thread<'a> {
    // expected public fields
}

impl<'a> Thread<'a> {
    pub fn new_thread(p: usize, c: String, t: &'a Workers) -> Thread {}
    pub fn skill(self) {}
}

Usage

Here is a program to test your function,

use std::rc::Rc;
use drop_the_thread::*;

fn main() {
    let worker = Workers::new();
    let (id, thread) = worker.new_worker(String::from("command"));
    let (id1, thread1) = worker.new_worker(String::from("command1"));

    thread.skill();

    println!("{:?}", (worker.is_dropped(id), id, &worker.drops));

    thread1.skill();
    println!("{:?}", (worker.is_dropped(id1), id1, &worker.drops));

    let (id2, thread2) = worker.new_worker(String::from("command2"));
    let thread2 = Rc::new(thread2);
    let thread2_clone = thread2.clone();

    drop(thread2_clone);

    println!("{:?}", (worker.is_dropped(id2), id2, &worker.drops, Rc::strong_count(&thread2)));
}

And its output:

$ cargo run
(true, 0, Cell { value: 1 })
(true, 1, Cell { value: 2 })
(false, 2, Cell { value: 2 }, 1)
$