Remix.run Logo
adwn 11 hours ago

When you construct an object containing a mutex, you have exclusive access to it, so you can initialize it without locking the mutex. When you're done, you publish/share the object, thereby losing exclusive access.

    struct Entry {
        msg: Mutex<String>,
    }
    ...
    // Construct a new object on the stack:
    let mut object = Entry { msg: Mutex::new(String::new()) };
    // Exclusive access, so no locking needed here:
    let mutable_msg = object.msg.get_mut();
    format_message(mutable_msg, ...);
    ...
    // Publish the object by moving it somewhere else, possibly on the heap:
    global_data.add_entry(object);
    // From now on, accessing the msg field would require locking the mutex
jstimpfle 7 hours ago | parent [-]

Initialization is always special. A mutex can't protect that which doesn't exist yet. The right way to initialize your object would be to construct the message first, then construct the composite type that combines the message with a mutex. This doesn't require locking a mutex, even without any borrow checker or other cleverness.

adwn 7 hours ago | parent [-]

Dude, it's a simplified example, of course you can poke holes into it. Here, let me help you fill in the gaps:

    let mut object = prepare_generic_entry(general_settings);
    let mutable_msg = object.msg.get_mut();
    do_specific_message_modification(mutable_msg, special_settings);
The point is, that there are situations where you have exclusive access to a mutex, and in those situations you can safely access the protected data without having to lock the mutex.
jstimpfle 7 hours ago | parent [-]

Sorry, I don't find that convincing but rather construed. This still seems like "constructor" type code, so the final object is not ready and locking should not happen before all the protected fields are constructed.

There may be other situations where you have an object in a specific state that makes it effectively owned by a thread, which might make it possible to forgo locking it. These are all very ad-hoc situations, most of them would surely be very hard to model using the borrow checker, and avoiding a lock would most likely not be worth the hassle anyway.

Not sure how this can help me reduce complexity or improve performance of my software.