On Tuesday, 16 October 2018 at 06:21:22 UTC, Manu wrote:
On Mon, Oct 15, 2018 at 8:55 PM Isaac S. via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

On Tuesday, 16 October 2018 at 02:26:04 UTC, Manu wrote:
>> I understand your point but I think the current shared (no >> implicit conversion) has its uses.
>> *snip*
>
> If you can give a single 'use', I'm all ears ;)

My usages are a custom ref counted template and list types (which are built on top of the former). The ref counted template will initialize naively when not shared but utilize compare-and-set and thread yielding if needed when shared (ensureInitialized can occur any time after declaration). The list types (which are not shared-compatible *yet*) will utilize a read-write mutex only when shared (no cost beyond a little unused memory to non-shared objects). As such, casting any of the non-shared versions of these types to shared would be unsafe.

(Technically the types can be safely casted to shared so long as no non-shared reference to them exists and vice versa.)

Can you link to code? It doesn't sound incompatible with my proposal. Mutexes are blunt instruments, and easy to model. My whole suggestion has virtually no effect on the mutex protected case, which is what most people seem to talk about.

On Wednesday, 17 October 2018 at 00:26:58 UTC, Manu wrote:
*snip*

Overloading for shared and unshared is possible, and may be desirable in many cases. There are also many cases where the code duplication and tech-debt does not carry its weight. It should not be required, because it's not technically required.

Overloading for shared and unshared is my reason for not allowing implicit conversion on my types (I have no problems with implicit conversion being optional or disableable). The unshared function performs no synchronization of any kind while the shared function always does. This means that having an unshared and shared reference to the same object is unsafe.

As for an actual link to code, I can really only link to my ref counted template as I haven't gotten around to making the containers shared-compatible yet. The main point of interest is at lines 103-131:

https://github.com/isaacs-dev/Familiar/blob/66f1a94fc099601465e755d40a2c68bf4200cabd/containers/familiar/containers/safe_ref_counted.d#L103

The unshared ensureInitialized() doesn't worry about threads simultaneously calling it. The shared version of it uses compare-and-set to prevent two threads from initializing it at the same time. An unsafe example would require a shared reference/pointer to an unshared SafeRefCounted (which would be fairly weird to do) and both calling ensureInitialized. While an example using the ref counted template is fairly contrived, a list-type that only uses a read-write mutex when it's shared isn't.


As to the larger part of preventing reading/writing of shared objects, I agree with its purpose and have no problems with it.

Reply via email to