TalG
TalG

Reputation: 748

Returning a value from a function that spawns threads

I'm trying to return a String using pop() in a thread:

use crossbeam_utils::thread; // 0.7.2
use std::sync::{Arc, Mutex};

pub struct MyText {
    my_text: Mutex<Vec<String>>,
}

pub trait MyTextOptions {
    fn get(&self) -> String;
}

impl MyTextOptions for MyText {
    fn get(&self) -> String {
        let mut int_text = Arc::new(self);
        thread::scope(|scope| {
            scope.spawn(|_| {
                let mut text_feed = int_text.my_text.lock().unwrap();
                text_feed.pop().unwrap()
            });
        })
        .unwrap()
    }
}

When I try to run it I get:

error[E0308]: mismatched types
  --> src/lib.rs:15:9
   |
13 |       fn get(&self) -> String {
   |                        ------ expected `std::string::String` because of return type
14 |           let mut int_text = Arc::new(self);
15 | /         thread::scope(|scope| {
16 | |             scope.spawn(|_| {
17 | |                 let mut text_feed = int_text.my_text.lock().unwrap();
18 | |                 text_feed.pop().unwrap()
19 | |             });
20 | |         })
21 | |         .unwrap()
   | |_________________^ expected struct `std::string::String`, found `()`

I don't understand why it is not returning the popped String value in text_feed.pop().unwrap().

Upvotes: 4

Views: 10524

Answers (1)

The first problem is the following line:

text_feed.pop().unwrap()

You want an expression in order to return something, so you should remove the ;.

Once you do so, you hit the second problem: the return value of thread::scope will be of type crossbeam_utils::thread::ScopedJoinHandle but you want a String. The docs states that it has a join().

Putting it all together we get:

use crossbeam_utils::thread; // 0.7.2
use std::sync::{Arc, Mutex};

pub struct MyText {
    my_text: Mutex<Vec<String>>,
}

pub trait MyTextOptions {
    fn get(&self) -> String;
}

impl MyTextOptions for MyText {
    fn get(&self) -> String {
        let int_text = Arc::new(self);
        thread::scope(|scope| {
            scope
                .spawn(|_| {
                    let mut text_feed = int_text.my_text.lock().unwrap();
                    text_feed.pop().unwrap()
                })
                .join()
                .unwrap()
        })
        .unwrap()
    }
}

Upvotes: 4

Related Questions