[phobos] Strange design of core.sync.condition in D

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Sep 13 18:54:45 UTC 2018

On Thursday, September 13, 2018 5:00:31 AM MDT Michael Galuza via phobos 
> Class core.sync.Mutex has shared and non-shared versions of its methods.
> This is logical — mutex is shared between threads. But class
> core.sync.Condition doesn't have shared methods at all. Why? Maybe I
> missed something, but it's very strange for me, because such code doesn't
> work: ---class Foo {    private Mutex mtx;    private Condition cnd;
>     shared this() {        mtx = new Mutex(this); // error: no constructor
> Mutex(shared Object)        cnd = new Condition(mtx); // error: no
> constructor Condition(shared Mutex)    }}---
> Please enlighten me)

It's likely because they predate shared, and when shared was added, the main
person maintaining that code was very leery of adding shared to anything
until shared was better sorted out. shared has since been added to some of
that stuff, but it hasn't been added consistently. I'd have to look them
over in detail to say for sure which should and should be shared, but
probably pretty much all of the methods on Mutex and Condition should be
shared. Mutex probably has both shared and non-shared in order to avoid
breaking code, and Condition has probably simply never been updated. Because
we have synchronized and std.concurrency in the language, Mutex and
Conditional don't need to be used directly anywhere near as much as they
would be with most languages, and even though it's a terrible idea, many
folks have tended to use __gshared instead of shared, because then the
compiler won't scream at them about trying to do something with shared
(which then risks serious bugs, because the compiler assumes that anything
that isn't shared is thread-local).

In general, shared objects shouldn't be able to do much of anything unless
they're protected by a mutex and have shared temporarily cast away, but
mutexes and conditional variables are one of the few instances where it does
make sense to have a shared object that actually has stuff called on it as
shared. The big problem overall though is that while the basics of shared
were figured out years ago, the details were never completed (e.g. copying
shared objects is not thread-safe, so it shouldn't be legal, but it is, and
some of the runtime and standard library stuff isn't set up properly to use
shared - as if you've found here). Walter and Andrei intend to finish
designing the fine details of shared, but it hasn't gotten high enough up on
the priority list yet to have actually happened yet. And because that hasn't
happened yet, shared hasn't gotten enough of a focus as it should have for
stuff like ensuring that the stuff in druntime is marked with shared

And avoiding code breakage when code has actually been updated has been a
bit entertaining - e.g. IIRC, most of the functions on Mutex really should
be nothrow, but because Mutex is a class and folks can derive from it,
adding nothrow would break existing code, and vibe.d had derived from it to
do something. So, while this stuff does need to get sorted out, it's not
always easy to do cleanly.

- Jonathan M Davis

More information about the phobos mailing list