https://github.com/atilaneves/fearless
  
  
    Safe concurrency in D (`shared` made easier) 
    https://github.com/atilaneves/fearless
  
concurrency d dip1000 dlang dlanguage lifetimes multithread multithreading mutex mutex-synchronisation nogc ownership reference-counting rust rust-lang rust-language rustlang safe safety threading
        Last synced: 7 months ago 
        JSON representation
    
Safe concurrency in D (`shared` made easier)
- Host: GitHub
- URL: https://github.com/atilaneves/fearless
- Owner: atilaneves
- License: bsl-1.0
- Created: 2018-05-22T20:34:15.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-04-22T17:36:09.000Z (over 1 year ago)
- Last Synced: 2025-03-24T02:05:32.636Z (7 months ago)
- Topics: concurrency, d, dip1000, dlang, dlanguage, lifetimes, multithread, multithreading, mutex, mutex-synchronisation, nogc, ownership, reference-counting, rust, rust-lang, rust-language, rustlang, safe, safety, threading
- Language: D
- Homepage:
- Size: 41 KB
- Stars: 54
- Watchers: 5
- Forks: 3
- Open Issues: 0
- 
            Metadata Files:
            - Readme: README.md
- License: LICENSE
 
Awesome Lists containing this project
README
          # fearless
[](https://travis-ci.org/atilaneves/fearless)
[](https://codecov.io/gh/atilaneves/fearless)
Safe concurrency in D
This package implements `@safe` easy sharing of mutable data between threads without having
to cast from shared and lock/unlock a mutex. It does so by using `scope` and
[DIP1000](https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md). It was inspired by
Rust's [std::sync::Mutex](https://doc.rust-lang.org/1.21.0/std/sync/struct.Mutex.html).
The main type is `Exclusive!T` which is safely shareable between
threads even if T is not `immutable` or `shared`. To create one, call
one of `gcExclusive` or `rcExclusive` with the parameters to the
constructor to create a type T. Passing an already created T would not
be safe since references to it or its internal data might exist
elsewhere.
As the names indicate, `gcExclusive` allocates on the GC heap, whereas `rcExclusive` uses
`RefCounted` from [automem](https://github.com/atilaneves/automem). This works automatically
if automem can be imported, which is always the case when automem is listed as a DUB
dependency.
To actually get access to the protected value, use `.lock()` (`borrow`
exists as an alias) to get exclusive access for the current block of
code.
An example (notice that `main` is `@safe`):
```d
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`
    {
        int* oldIntPtr;  // only here to demonstrate 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(
        // ref Exclusive!Foo doesn't compile, use pointer instead
        (Exclusive!Foo* m) {
            auto xfoo = m.lock;
            xfoo.i++;
        },
    );
    tid.send(Ended());
}
void safeWriteln(A...)(auto ref A args) { // for some reason the writelns here are all @system
    import std.stdio: writeln;
    import std.functional: forward;
    () @trusted { writeln(forward!args); }();
}
```
This program prints:
```
i: 42
i: 1
i: 2
```
Please consult the examples directory and/or unit tests for more.