- r00ty ( @r00ty@kbin.life ) 13•2 months ago
I started playing with rust last week (just converting a couple of C# projects so far), and I’m going to say that once you understand that mutexes/rwlocks are wrappers around the actual data, it (to me at least) feels better.
Don’t get me wrong, it’s an absolute headache for anyone that’s acquired intermediate or better skill in one of the Cx languages. The paradigm shift is still hitting me hard. But this was one of the differences I actually think is an improvement in probably most use cases.
- 5C5C5C ( @5C5C5C@programming.dev ) 13•2 months ago
It’s a massive win, and I would question the credibility of any systems programmer that doesn’t recognize that as soon as they understand the wrapper arrangement. I would have to assume that such people are going around making egregious errors in how they’re using mutexes in their C-like code, and are the reason Rust is such an important language to roll out everywhere.
The only time I’ve ever needed a
Mutex<()>
so far with Rust is when I had to interop with a C library which itself was not thread safe (unprotected use of global variables), so I needed to lock the placeholder mutex each time I called one of the C functions.- SorteKanin ( @SorteKanin@feddit.dk ) 4•2 months ago
The only time I’ve ever needed a Mutex<()> so far with Rust is when I had to interop with a C library which itself was not thread safe (unprotected use of global variables), so I needed to lock the placeholder mutex each time I called one of the C functions.
Actually I think in this case you’re still better off using a Mutex with “data” inside. I’ve done this before. The idea is that you make a unit struct
MyCFuncs
or whatever and then you only call the C functions from methods of that unit struct. Then you can only access those methods once you lock the Mutex and get the instance of the unit struct. It feel elegant to me.- 5C5C5C ( @5C5C5C@programming.dev ) 1•2 months ago
This makes a lot of sense, but the functions were Rust bindings for plain C functions, they weren’t function pointers. Granted I could have put pointers to the function bindings into fields in a struct and stored that struct in the mutex, but the ability to anyhow call the bindings would still exist.
- SorteKanin ( @SorteKanin@feddit.dk ) 1•2 months ago
They were also plain C functions in my case, but it doesn’t take too much discipline to only call it through the struct. Also, you can put the struct in a different crate which includes the C bindings to ensure that you can’t call the C bindings without the struct.
- noddy ( @noddy@beehaw.org ) 8•2 months ago
Wrapping a value in a mutex just makes sense. After learning a bit of Rust I made a similar mutex wrapper in C++ when I had to protect a class member in a C++ project. I just had to change the type in the declaration, and bam the compiler tells me about all places this member was accessed. Much easier than using some buggy ‘find all references’, potentially forgetting a few places.
- lolcatnip ( @lolcatnip@reddthat.com ) English4•2 months ago
Looks like the author missed my main complaint about Rust mutexes, which is that the
lock
method returns aResult
. There should be atry_unlock
method for when someone actually wants to handle the rather obscure failure case, and the namelock
should be used for a method that panics on failure but returns a value that doesn’t need to be unwrapped first. I see the current arrangement as being about as sensible as having array subscripting return aResult
to handle the case of a failed bounds check.- BB_C ( @BB_C@programming.dev ) 8•2 months ago
If lock-ergonomicsⓒ is as relevant to you as indexing, you’re doing it wrong.
I would rather take indexing returning
Result
s than the other way around.One can always wrap any code in
{||{ //.. }}()
and use question marks liberally anyway (I call them stable try blocks 😉). - SorteKanin ( @SorteKanin@feddit.dk ) 3•2 months ago
Just use the Mutex from the parking_lot crate.