all OS functions should be "nothrow @trusted @nogc"
Moritz Maxeiner via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jul 26 02:06:19 PDT 2017
On Wednesday, 26 July 2017 at 06:44:51 UTC, Shachar Shemesh wrote:
> On 25/07/17 18:29, Moritz Maxeiner wrote:
>> On Tuesday, 25 July 2017 at 14:39:15 UTC, Shachar Shemesh
>> wrote:
>>> On 25/07/17 17:24, Moritz Maxeiner wrote:
>>>> On Tuesday, 25 July 2017 at 13:50:16 UTC, Shachar Shemesh
>>>> wrote:
>>>>> The title really does says it all.
>>>>
>>>> Since you explicitly state *all* OS functions:
>>>> nothrow: Should be OK (only callbacks could violate this and
>>>> they should be nothrow, anyway).
>>> Technically, any system call that is a pthreads cancellation
>>> point may throw a C++ exception.
>>
>> Good to know, then since D is supposed to be able to catch C++
>> exceptions (and can on 64bit Linux [1]) none of those may be
>> attributed as `nothrow`, because C++ exceptions don't derive
>> from `Error` >
>>>
>>> If we go down that route, however, calling system calls from
>>> nothrow becomes completely impossible, which is another way
>>> of saying that decorating just about anything with nothrow
>>> becomes impossible.
>>
>> No. `nothrow` functions can call throwing ones, as long as
>> they catch any exceptions not derived from Error thrown by
>> them.
>>
>
> And right there and then you've introduced a serious problem.
> The purpose of the C++ exception thrown on cancellation point
> is to terminate the thread. It is designed to be uncatchable.
The issue lies with the definition of `nothrow` considering only
D Throwables;
it would have to be updated to apply to C++ exceptions that
equate to D exceptions derived from Error.
>
> I think labeling these "nothrow" is the correct course of
> action.
Not with the `nothrow` spec as it is right now. After the spec
having been updated to apply to C++ exception that may not be
caught, sure.
>>> I'm not sure this is the most compelling argument, however.
>>> The function passed to pthread_create does not, logically,
>>> run in the pthread_create function. As such, I don't think
>>> this logic holds.
>>
>> Then the @nogc definition would need to be updated from: "or
>> indirectly through functions it may call" to reflect this,
>> because that can be interpreted both ways.
>>
>>>
>>> As for pthread_join, I have no idea what you meant by it.
>>> Please elaborate why you think it is a problem.
>>
>> Possible scenario on single core (no hyperthreading) system:
>> - thread 1 spawns thread 2
>> - thread 1 enters @nogc function `foo` and calls
>> `pthread_join` on thread 2 before its own timeslice is over
>> (and thus enters blocked state)
>> - thread 2 does work allocating via the GC, then terminates
>> - thread 1 wakes up and leaves @nogc function `foo`
>>
>> Because @nogc (in contrast to nothrow) is explicitly designed
>> as transitive, logically speaking, `foo` violated its @nogc
>> constraint (it *caused* the GC allocations in thread 2).
>
> Following that logic, ANY function that might affect another
> thread cannot be @nogc.
Not any function; as I interpret the spec only those who manually
interleave another thread allocating via the GC such that it
looks to a caller as if they had allocated using the GC.
> I think this way madness lies. I don't think other threads
> action, even if linked in some weird semantic way to ours, make
> us accountable to their actions.
I would say it depends on the exact semantics of each use case
whether we are accountable.
>
> If you pass a callback that is not @nogc to pthread_create,
> then your other thread might allocate. This doesn't change the
> fact that pthread_create doesn't allocate.
The "indirectly through functions it may call" of the @nogc spec
is ambiguous here because it doesn't actually require a direct
call chain to the allocation. It would need to be updated.
> At Weka, we use this understanding of the semantics all the
> time. Our main thread is as @nogc as we can possibly make it.
> Whenever we need anything that violates our usual restrictions,
> we send it either to other threads or other processes for
> execution, and use the results when they return. Defining the
> various attributes too strictly will simply mean we cannot use
> them anywhere (which is pretty much what happens today, but the
> very thing I'm trying to change here).
There is a difference between what's sensible and what the
current wording of the spec allows for and before it's OK to
attribute functions where the ambiguity applies, the spec wording
(for both @nogc and nothrow) has to be made unambiguous.
P.S.: In case it's not clear: I'm playing devil's advocate in
this subthread.
More information about the Digitalmars-d
mailing list