On Sunday, 21 October 2018 at 12:45:43 UTC, Stanislav Blinov wrote:
On Sunday, 21 October 2018 at 05:47:14 UTC, Manu wrote:
On Sat, Oct 20, 2018 at 10:10 AM Stanislav Blinov via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

Synchronized with what? You still have `a`, which isn't `shared` and doesn't require any atomic access or synchronization. At this point it doesn't matter if it's an int or a struct. As soon as you share `a`, you can't just pretend that reading or writing `a` is safe.

`b` can't read or write `a`... accessing `a` is absolutely safe.

It's not, with or without your proposal. The purpose of sharing `a` into `b` is to allow someone to access `*a` in a threadsafe way (but un-@safe, as it *will* require casting away `shared` from `b`). That is what's making keeping an unshared reference `a` un-@safe: whoever accesses `*a` in their @trusted implementations via `*b` can't know that `*a` is being (@safe-ly!) accessed in a non-threadsafe way at the same time.

Then someone has not done their job. Since the pieces of code that will actually use the un-@safe building blocks at the bottom are few and far between, it is reasonable to assume that an expert will be writing this code, and that such code be placed in a separate module where all access to the shared type is controlled.

It seems you expect regular users to have calls to atomicOp!"++" scattered all over their code. I find this an unreasonable expectation, and fully agree that this will lead to problems.


Someone must do something unsafe to undermine your threadsafety... and if you write unsafe code and don't know what you're doing, there's
nothing that can help you.

Ergo, it follows that anyone that is making an implicit cast from mutable to shared better know what they're doing, which mere mortal users (not "experts") might not. I.e. it's a way to giving a loaded gun to someone who never held a weapon before.

No.


Close does not promise threadsafety itself (but of course, it doesn't violate read/write's promise, or the program is invalid).

Yep, and that's the issue. It SHALL NOT violate threadsafety, but it can't promise such in any way :(

Can you demonstrate any system that can promise something like that? (apart from all-immutable)


read and write will appropriately check their file-open state each time they perform their actions.

Why? The only purpose of giving someone a `shared` reference is to give a reference to an open file. `shared` references can't do anything with the file but read and write, they would expect to be able to do so.

Because otherwise it's not thread-safe. Exactly as you point out, the owner could call closeFile before some other thread was finished writing. If the implementer of FileHandle fails to take this into account, then no, it's not thread-safe.


I'm going to assume that `shareWithThreads()` was implemented by an 'expert' who checked the function results for errors. It was detected that the reads/write failed, and an error "failed to read file" was emit, then the function returned promptly.
The uncertainty of what happens in this program is however
`shareWithThreads()` handles read/write emitting an error.

But you can only find out about these errors in `waitForThreads`, the very call that the user "forgot" to make!

Of course not. You can throw exceptions, you could add a destructor that reports on these errors, you could set an error flag somewhere and check that every now and then. The fact that you've managed to write a horribly broken API under MP and can't see a way to do better inside that system does not necessarily mean the problem is with MP.

--
  Simen

Reply via email to