Search code examples
rustrust-tokio

Waiting on multiple futures borrowing mutable self


Each of the following methods need (&mut self) to operate. The following code gives the error.

cannot borrow *self as mutable more than once at a time

How can I achieve this correctly?

loop {
        let future1 = self.handle_new_connections(sender_to_connector.clone());
        let future2 = self.handle_incoming_message(&mut receiver_from_peers);
        let future3 = self.handle_outgoing_message();

        tokio::pin!(future1, future2, future3);
        tokio::select! {
            _=future1=>{},
            _=future2=>{},
            _=future3=>{}
        }
    }

Solution

  • You are not allowed to have multiple mutable references to an object and there's a good reason for that. Imagine you pass an object mutably to 2 different functions and they edited the object out of sync since you don't have any mechanism for that in place. then you'd end up with something called a race condition.

    To prevent this bug rust allows only one mutable reference to an object at a time but you can have multiple immutable references and often you see people use internal mutability patterns.

    In your case, you want data not to be able to be modified by 2 different threads at the same time so you'd wrap it in a Lock or RwLock then since you want multiple threads to be able to own this value you'd wrap that in an Arc.

    here you can read about interior mutability in more detail.

    Alternatively, while declaring the type of your function you could add proper lifetimes to indicate the resulting Future will be waited on in the same context by giving it a lifetime since your code waits for the future before the next iteration that would do the trick as well.