Jump to page: 1 2
Thread overview
fearless v0.0.1 - shared made easy (and @safe)
Sep 18, 2018
Atila Neves
Sep 18, 2018
Paolo Invernizzi
Sep 18, 2018
12345swordy
Sep 18, 2018
shfit
Sep 19, 2018
Atila Neves
Sep 19, 2018
Claude
Sep 19, 2018
Atila Neves
Sep 19, 2018
thedeemon
Sep 19, 2018
H. S. Teoh
Sep 20, 2018
Guillaume Piolat
Sep 20, 2018
Atila Neves
September 18, 2018
The `shared` keyword currently means one of two things:

1. You can use core.atomic with it
2. It's some struct and you BYOM (Bring Your Own Mutex)


Do you have to send mutable data to other threads? Are you tired of locking a mutex and casting? Now you don't have to:


https://code.dlang.org/packages/fearless


I was envious of std::sync::Mutex from Rust and thought: can I use DIP1000 to make this work in D and be @safe? Turns out, yes.

I'm going to write a blog post about this explaining the why and how. I'm too tired right now though, so here's some code:


// compile with -dip1000
import fearless;


struct Foo {
    int i;
}

int* gEvilInt;


void main() @safe {

    // create an instance of Exclusive!Foo allocated on the GC heap
    auto foo = gcExclusive!Foo(42);
    // from now the value inside `foo` can only be used by calling `lock` (a.k.a. `borrow`)

    {
        int* oldIntPtr; // only here to demostrate scopes, see below
        auto xfoo = foo.lock();  // get exclusive access to the data (this locks a mutex)

        safeWriteln("i: ", xfoo.i);
        xfoo.i = 1;
        safeWriteln("i: ", xfoo.i);

        // can't escape to a global
        static assert(!__traits(compiles, gEvilInt = &xfoo.i));

        // ok to assign to a local that lives less
        int* intPtr;
        static assert(__traits(compiles, intPtr = &xfoo.i));

        // not ok to assign to a local that lives longer
        static assert(!__traits(compiles, oldIntPtr = &xfoo.i));
    }

    // Demonstrate sending to another thread and mutating
    auto tid = spawn(&func, thisTid);
    tid.send(foo);
    receiveOnly!Ended;
    safeWriteln("i: ", foo.lock.i);
}

struct Ended{}

void func(Tid tid) @safe {
    receive(
        (Exclusive!Foo* m) {
            auto xfoo = m.lock;
            xfoo.i++;
        },
    );

    tid.send(Ended());
}

// for some reason the writelns here are all @system
void safeWriteln(A...)(auto ref A args) {
    import std.stdio: writeln;
    import std.functional: forward;
    () @trusted { writeln(forward!args); }();
}

September 18, 2018
On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
> The `shared` keyword currently means one of two things:
>
> 1. You can use core.atomic with it
> 2. It's some struct and you BYOM (Bring Your Own Mutex)
>
> [...]

Whaaaaaaaaahhhhhh!!!!!!  You made my day!

/Paolo
September 18, 2018
On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
> The `shared` keyword currently means one of two things:
>
> 1. You can use core.atomic with it
> 2. It's some struct and you BYOM (Bring Your Own Mutex)
>
> [...]

Why is this is an external 3rd party library isn't of the standard library?

-Alexander
September 18, 2018
On Tuesday, 18 September 2018 at 17:34:10 UTC, 12345swordy wrote:
> On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
>> The `shared` keyword currently means one of two things:
>>
>> 1. You can use core.atomic with it
>> 2. It's some struct and you BYOM (Bring Your Own Mutex)
>>
>> [...]
>
> Why is this is an external 3rd party library isn't of the standard library?
>
> -Alexander

Agreed, this is great!
September 19, 2018
On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
> I was envious of std::sync::Mutex from Rust and thought: can I use DIP1000 to make this work in D and be @safe? Turns out, yes.

Beautiful! The only current downside, is the fact the application using that library has to be compiled with -dip1000 if I'm not wrong?

September 19, 2018
On Tuesday, 18 September 2018 at 17:34:10 UTC, 12345swordy wrote:
> On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
>> The `shared` keyword currently means one of two things:
>>
>> 1. You can use core.atomic with it
>> 2. It's some struct and you BYOM (Bring Your Own Mutex)
>>
>> [...]
>
> Why is this is an external 3rd party library isn't of the standard library?
>
> -Alexander

Because it's far easier to release something with dub. If it gets traction then it might be a candidate for inclusion in Phobos.
September 19, 2018
On Wednesday, 19 September 2018 at 07:33:55 UTC, Claude wrote:
> On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
>> I was envious of std::sync::Mutex from Rust and thought: can I use DIP1000 to make this work in D and be @safe? Turns out, yes.
>
> Beautiful! The only current downside, is the fact the application using that library has to be compiled with -dip1000 if I'm not wrong?

Thanks!

You only have to compile with -dip1000 if you want guarantees about safety... ;)
September 19, 2018
On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:

> I was envious of std::sync::Mutex from Rust and thought: can I use DIP1000 to make this work in D and be @safe? Turns out, yes.

Nice! I spent a few minutes playing with the example and trying to break it, make the pointer escape, but I couldn't, the compiler caught me every time. This DIP1000 thing seems to be working!
September 19, 2018
On 9/19/18 6:44 AM, Atila Neves wrote:
> On Tuesday, 18 September 2018 at 17:34:10 UTC, 12345swordy wrote:
>> On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
>>> The `shared` keyword currently means one of two things:
>>>
>>> 1. You can use core.atomic with it
>>> 2. It's some struct and you BYOM (Bring Your Own Mutex)
>>>
>>> [...]
>>
>> Why is this is an external 3rd party library isn't of the standard library?
> 
> Because it's far easier to release something with dub. If it gets traction then it might be a candidate for inclusion in Phobos.

I'll also add that if it depends on dip1000, Phobos isn't ready for that anyway.

But if Phobos does end up getting to that point, this 100% should be in the standard library. It's a no-brainer.

-Steve
September 19, 2018
On Wed, Sep 19, 2018 at 10:58:04AM +0000, thedeemon via Digitalmars-d-announce wrote:
> On Tuesday, 18 September 2018 at 17:20:26 UTC, Atila Neves wrote:
> > I was envious of std::sync::Mutex from Rust and thought: can I use DIP1000 to make this work in D and be @safe? Turns out, yes.
> 
> Nice! I spent a few minutes playing with the example and trying to break it, make the pointer escape, but I couldn't, the compiler caught me every time.  This DIP1000 thing seems to be working!

Finally, dip1000 is proving its value.


T

-- 
Doubt is a self-fulfilling prophecy.
« First   ‹ Prev
1 2