How to save a mut variable to a pool, and the variable be create in other thread

how to move a mut variable to it's parent scope

use std::path::Path;
extern crate websocket;
use std::collections::HashMap;
use std::net::TcpStream;
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use websocket::sender::Writer;
use websocket::OwnedMessage;

struct ConnectionPool {
    pool: Arc<Mutex<Box<HashMap<u32, Arc<Mutex<Box<&mut Writer<TcpStream>>>>>>>>,
                                                   // ^ error here
    sender: mpsc::Sender<String>,
    receiver: Arc<Mutex<Box<mpsc::Receiver<String>>>>,
}

impl ConnectionPool<'_> {
    pub fn new<'a>() -> ConnectionPool {
        let (tx, rx) = mpsc::channel();
        ConnectionPool {
            pool: Arc::new(Mutex::new(Box::new(HashMap::with_capacity(2)))),
            sender: tx,
            receiver: Arc::new(Mutex::new(Box::new(rx))),
        }
    }
    pub fn listen(&mut self, address: &str) {
        // Listen on an address and call the closure for each connection
        // let pool = self.pool.clone();
        println!("start wait message");
        self.recv();
        let server = websocket::sync::Server::bind(address).expect("bind fail");
        for req in server.filter_map(Result::ok) {
            let pool = self.pool.clone();
            thread::spawn(move || {
                let ip = client.peer_addr().unwrap();
                println!("Connection from {}", ip);
                let mut p = pool.lock().unwrap();
                let (mut receiver, mut sender) = client.split().unwrap();

                let sender = Arc::new(Mutex::new(Box::new(&mut sender))); 
                                                        // ^ error here
    
                p.insert(1, sender);
              
            });
        }
    }
    fn recv(&self) {
        let rx = self.receiver.clone();
        let pool = self.pool.clone();
        std::thread::spawn(move || loop {
            println!("check message chan");
            let r = rx.lock().unwrap();
            match r.recv() {
                Ok(s) => {
                    let p = pool.lock().unwrap();
                    p.iter().for_each(|(id, sender)| {
                        let send = sender.clone().lock().unwrap();
                        send.send_message(&OwnedMessage::Text(format!("id {}, message {}", id, s)))
                     // ^ error here
                            .unwrap();
                    })
                }
                Err(err) => {
                    println!("{}", err);
                }
            };
        });
    }
}

// -> std::io::Result<()>
fn main() {
    // Setup listen
    ConnectionPool::new().listen("127.0.0.1:3012")
}

In general this is what I would do if I needed to "lift" a binding to a higher scope:

fn main() {
    let dst: String;  // Allocate space for it
    {
        let tmp = String::from("foo"); // create a binding in a lower scope
        dst = tmp; // lift the binding to the higher scope of the main fn
    }
    println!("dst: {}", dst);
}

That said, in general I don't need this pattern all that often.

Sorry, maybe I'm not clear.

I mean that I want to build a socket poll, it save all socket sender, when someone receive a message , this message will be pass to a message channel, the receiver of this message channel will send message to all socket sender.

so, i need to save all socket sender to a pool, and I can use it in multiple thread. when i save the sender , i get an error in follow

i modified the type

i add a lifetime specifier in ConnectionPoll

....

but I got more error, i don't know how to fix them :sob:;

Remove the &mut. You should move ownership of the stream, but when using a reference, you're doing a borrow

I don't know how to write it

Do you still get errors if you remove the &mut?

yes , i got this error

i do this

Try marking it mutable with let mut

if set to mut , i will get the above error

i resolve it

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.