On Tuesday, October 04, 2016 19:22:10 Begah via Digitalmars-d-learn wrote: > How can I make a method that accepts being called by both a > shared and non-shared object, to prevent having to copy methods > and adding a "shared"?
You could templatize them, but really, the idea is that you _don't_ call much of anything on a shared object. It's not thread-safe to do so unless it's protected by a mutex or sychronized block. shared is as unwieldy as it is in part because it's easy to use incorrectly, and most code should not be using shared at all, because the stuff that actually needs to be shared across threads is normally pretty minimal. The fact that most operations are illegal on shared objects prevents misuse. But of course, it leaves the question of how you go about actually doing anything with a shared object, since obviously, you're going to do need to do more than just create the thing. TDPL talks about synchronized classes where the outer layer of shared gets automatically cast away within the member functions of the class (since the compiler can guarantee that only one thread at a time is in the member functions of the class). However, synchronized classes haven't been implemented as of yet, and we just have synchronized functions, which do protect those functions with a mutex, but without requiring that all functions within the class be synchronized and make it illegal to access the member variables except via the member functions, the compiler can't cast away the outer layer of shared, because it can't guarantee that the member is actually protected by a mutex. So, the way to solve this is that when you want to operate on a shared object, you first make sure that it's protected by a mutex (like you would in a language like C or C++), then you cast away shared to operate on the object, and then when you're done, you make sure that no non-shared references to the object exist, and release the mutex. e.g. something like shared MyClass mySharedObj = getSharedObj(); synchronized(myMutex) { auto obj = cast(MyClass)mySharedObj; // do stuff with obj... // obj should be the only non-shared reference to the object // referred to by mySharedObj when the sychronized block exits. } So, ultimately, the code is basically the same as what you'd do in C/C++ except that you have to cast away shared to actually do much of anything to the object. It _is_ unfortunately more error-prone than synchronized classes would be, because you're forced to do a manual cast, but since we don't actually have synchronized class, you don't have much choice, and since synchronized classes would only strip away the outer layer of shared, there's a halfway decent chance that you'd still need to do something like this even if we did have synchronized classes. - Jonathan M Davis