-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make keys Send and Sync, remove Clone #19
Comments
The headers should already document the thread-safety rules. They contain text like:
And, when some thread-safe functions aren't const for silly reasons,
Please let us know if we missed anything important. The intent is that you can use a key concurrently. TLS servers often do and indeed for RSA objects particularly, it's preferably to sharing them performance. (There's a blinding cache and, owing to some poor API decisions in OpenSSL, some parts of the private key need to be initialized lazily rather than when the key is created.) (Of course, it's not safe to use a key concurrently with mutating it, hence the const rule.) |
Oh! Not sure how I missed that, thanks!. I'll update the description accordingly. |
OK, @davidben let me know if the updated issue description seems accurate to you. |
Seems plausible. I don't know enough about Rust to evaluate the Send, Sync, and Clone proposal, so I'll leave that to you. On the subject of ref-counting or copying keys and They're a quirk of a problematic OpenSSL API pattern. Rather than making functions like |
Ah interesting. I think it's still probably worth not exposing |
Seems reasonable. For completeness, the built-in ref-counting would avoid an extra allocation and layer of indirection. For C++ code, I think we usually encourage folks to use ( |
That's fair, although given that crypto operations are so expensive (compared to pointer indirection), I don't think it's worth making an un-idiomatic API. |
To err on the safe side, we initially made our key objects neither
Send
norSync
. However, BoringSSL provides concurrency semantics for key objects that allow us to relax these restrictions. In particular, key objects' reference counts are incremented and decremented atomically, and all BoringSSL operations on keys have well-defined concurrency safety semantics.I propose that we implement
Sync
on key objects, and use BoringSSL's definition of which functions are mutating to decide which methods to have take a&mut self
vs a&self
receiver.An aside on
Clone
and reference countingCurrently, keys are reference counted, and cloning a Mundane key object obtains a new reference-counted reference to the same underlying object. Unfortunately, we cannot implement either
Send
orSync
so long as it's possible to obtain multiple references to the same underlying object.If reference-counted key objects are
Send
, then different clones could be sent to different threads, and we'd have no way of preventing those two separate clones from being operated on using&mut self
methods concurrently, which would be unsound.If reference-counted key objects are
Sync
, then different clones owned by one thread could be accessed concurrently from different threads, and we'd have no way of preventing those two separate clones from being operated on using&mut self
methods concurrently, which would be unsound.Thus, I conclude that we must remove the ability to clone key objects. The primary benefit to reference counting in BoringSSL is to be able to use keys concurrently from multiple threads at once. Since Rust's lifetime system allows us to share references across threads safely, we get the same advantage even without reference counting. Even if reference counting were desired, we could put a Mundane key object inside of an
Rc
or anArc
and get the same effect.Thus, the concrete tasks are:
Clone
key objects&mut self
methods, and document our strategy and reasoning in code commentsSend
andSync
on key objectsOld (incorrect) text:
The text was updated successfully, but these errors were encountered: