On 09/13/2015 09:09 AM, Alex wrote:
> I'm new to this forum so, please excuse me in advance for
> asking silly questions.

Before somebody else says it: There are no silly questions. :)

> struct std.typecons.Unique!(S).Unique is not copyable because it is
> annotated with @disable

I have made the code compile and work (without any thread synchronization at all). See the comments with [Ali] annotations:

import std.stdio;
import std.concurrency;
import std.typecons;

void spawnedFunc2(Tid ownerTid)
{
    /* [Ali] Aside: ownerTid is already and automatically
     * available. You don't need to pass it in explicitly. */

    receive(
        /* [Ali] The compilation error comes from Variant, which
         * happens to be the catch all type for concurrency
         * messages. Unfortunately, there are issues with that
         * type.
         *
         * Although implemented as a pointer, according to
         * Variant, a 'ref' is not a pointer. (I am not sure
         * whether this one is a Variant issue or a language
         * issue.)
         *
         * Changing the message to a pointer to a shared
         * object: */
        (shared(Unique!S) * urShared)
        {
            /* [Ali] Because the expression ur.i does not work on
             * a shared object, we will hack it to unshared
             * first. */
            auto ur = cast(Unique!S*)urShared;
            writeln("Recieved the number ", ur.i);
        }
    );
    send(ownerTid, true);
}

static struct S
{
    int i;
    this(int i){this.i = i;}
}

Unique!S produce()
{
    // Construct a unique instance of S on the heap
    Unique!S ut = new S(5);
    // Implicit transfer of ownership
    return ut;
}

void main()
{
    Unique!S u1;
    u1 = produce();
    auto childTid2 = spawn(&spawnedFunc2, thisTid);

    /* [Ali] Cast it to shared so that it passes to the other
     * side. Unfortunately, there is no guarantee that this
     * object is not used by more than one thread. */
    send(childTid2, cast(shared(Unique!S*))&u1);

    /* [Ali] We must wait to ensure that u1 is not destroyed
     * before all workers have finished their tasks. */
    import core.thread;
    thread_joinAll();

    writeln("Successfully printed number.");
}

Note that thread synchronization is still the programmer's responsibility.

> I'm aware of the fact, that my u1 struct can't be copied, but I don't
> intend to do so.

Correct.

> As in the docu stated, I want to lend the struct to the
> other thread (by using ref), being sure, that any other thread can't
> access the struct during it is processed by the first one.

There is a misconception. Unique guarantees that the object will not be copied. It does not provide any guarantee that only one thread will access the object. It is possible to write a type that acquires a lock during certain operations but Unique isn't that type.

> Is such a thing possible?
> Thanks in advance.
> Alex

Ali

Reply via email to