Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> The big win in Rust is that the mutexes are tied to the data they protect. The compiler won't let you access data until it's locked.

You can get this kind of behavior in C++ with, e.g., folly::Synchronized<T>.



I will play the devil's advocate and say: You can get any behaviour in C++, but there are so many options almost nobody is using them, or using them the right way.

And this is coming from someone that has written a lot of C++ and no Rust at all..


Rust's borrow checker will of course check that if you borrowed the protected item you've given it back before unlocking, whereas all Folly and similar C++ libraries can do here is caution you that this footgun exists and is loaded and pointed at your foot so please don't.


That's just the usual resource ownership management problem that Rust is supposed to solve.

But a simple templated type like GP proposed does indeed fix the issue discussed here. To access the thing in the first place you need to lock the correct mutex. Looking at Folly::Synchronized, locking doesn't even return the protected item itself directly. In most cases -- unless the bare pointer is needed -- you will access the item through the returned "locked view" object which does the unlocking in its destructor.


Sure, Rust "just" enforces type safety. But without type safety a type can't help us much more than the textual advice did so I think that's a really big difference, especially at scale.

In a small problem the textual advice is enough, I've written gnarly C with locks that "belong" to an object and so you need to make sure you take the right lock before calling certain functions which touch the object. The textual advice (locks are associated with objects) was good enough for that code to be correct -- which is good because C has no idea how to reflect this nicely in the language itself nor does it have adequate type safety enforcement.

But in a large problem enforcement makes all the difference. I had maybe two kinds of lock, a total of a dozen functions which need locking, it was all in my head as the sole programmer on that part of the system. But if we'd scaled up to a handful of people working on that code, ten kinds of lock, a hundred functions needing locking I'd be astonished if it didn't begin to have hard to debug issues or run into scaling challenges as everybody tries to "keep it simple" when that's no longer enough.


GP isn't totally wrong. With folly::Synchronized, you can lock, take a reference, then unlock, and continue to (incorrectly/unsafely) use the reference. The compiler doesn't catch that.

  folly::Synchronized<int> lockedObj;
  auto lockHandle = lockedObj.wlock();
  auto& myReference = *lockHandle;
  lockHandle.unlock();
  myReference = 5; // bad
Still, it is harder to misuse than bare locks unattached to data.


Yes, but you can also take a reference (copy a pointer), delete, and continue to use the reference etc. I was pointing out that this is simply a lifetime/ownership issue, not an issue specific to locking (and yes, Rust solves that issue, at least for the easy cases). And as far as the problem is protecting access to a locked resource, a class like folly::Synchronized does indeed solve the problem.


Yes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: