|
|
Subscribe / Log in / New account

Bjarne Stroustrup’s Plan for Bringing Safety to C++ (The New Stack)

Bjarne Stroustrup’s Plan for Bringing Safety to C++ (The New Stack)

Posted Nov 2, 2023 22:42 UTC (Thu) by mathstuf (subscriber, #69389)
In reply to: Bjarne Stroustrup’s Plan for Bringing Safety to C++ (The New Stack) by farnz
Parent article: Bjarne Stroustrup’s Plan for Bringing Safety to C++ (The New Stack)

There are times that you can screw things up in Rust, but it's around things that a compiler (understandably) has no knowledge of. It's not UB, but a deadlock still isn't nice. Take this anecdote.

We had deadlocks in a few tests in the test suite. Fine, rerun the CI job when it happens…usually OK. When I finally got around to tracking it down, it turns out that it is 100% in the test suite itself (so doesn't affect the deployment; I kind of knew this already and it was why it was on the backburner for so long):

- we have one thread act as a "hosting service" that takes the role of a forge dealing with git hook calls triggering webhook events and such;
- one thread acts as the "client" for the tests to emulate performing actions;
- there is a shared RwLock'd data block so that the client can get access read-only data access as needed (avoiding the need for synchronous channel communications on the client side);
- there is a sized channel to send requests to the service (in lieu of HTTP in normal usage).

In the deadlock, the "service" side was blocked waiting on write access to the data to handle an event. The "client" was blocked on the full channel trying to send a new event. However, it did so while holding a read-only lock on that shared data structure. Sure, an unbuffered channel would have worked too, but that seemed "hacky" to me. Instead, the fix is to only send events on the channel when the read lock is *not* held. That is fixed here:

https://gitlab.kitware.com/utils/ghostflow-director/-/com...

C++ would have had the same fix for this problem. Fine, the test suite is happy.

However, I knew that over time, guaranteeing that the read lock was not held anywhere in the call stack when sending on the channel was a hard problem. But Rust enforces "mutable XOR shared" access, so the "this will never happen again" fix is possible:

https://gitlab.kitware.com/utils/ghostflow-director/-/com...

Now, access to a read lock is mediated through a `&mut` reference to a struct containing the channel and the data. Sending on the channel *also* requires a `&mut` reference. The compiler will therefore enforce that if the channel is accessed, the data lock is not held (as to get it, you need to hold a `&mut` reference to the structure).

This is the kind of stuff one can construct with Rust's rules: not only is the bug fixed, but *it can never happen again*.


to post comments

Bjarne Stroustrup’s Plan for Bringing Safety to C++ (The New Stack)

Posted Nov 3, 2023 11:27 UTC (Fri) by farnz (subscriber, #17727) [Link]

That's the sort of thing I was thinking of with "CI is green" checks; you've been able to take a hard problem, and convert it to "if CI goes green, then the problem doesn't exist". Because developers use "CI is green" as a short-cut for "the code works as intended", doing this means that taking that short-cut is OK.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds