On 09/14/2015 12:07 AM, Alex wrote: > Do you have a hint how to create such a type? The needed operation is > "onPassingTo" another thread. So the idea is to create a resource, which > is not really shared (a question of definition, I think), as it should > be accessible only from one thread at a time. > But there is a "main" thread, from which the resource can be lent to > "worker" threads and there are "worker" threads, where only one worker > can have the resource at a given time.
Here is an unpolished solution that enforces that the thread that is using it is really its owner:
struct MultiThreadedUnique(T) { Tid currentOwner; Unique!T u; this(Unique!T u) { this.u = u.release(); this.currentOwner = thisTid; } void enforceRightOwner() { import std.exception; import std.string; enforce(currentOwner == thisTid, format("%s is the owner; not %s", currentOwner, thisTid)); } ref Unique!T get() { enforceRightOwner(); return u; } void giveTo(Tid newOwner) { enforceRightOwner(); currentOwner = newOwner; } } The entire program that I tested it with: import std.stdio; import std.concurrency; import std.typecons; void spawnedFunc2(Tid ownerTid) { receive( (shared(MultiThreadedUnique!S) * urShared) { auto ur = cast(MultiThreadedUnique!S*)urShared; writeln("Recieved the number ", ur.get().i); ur.giveTo(ownerTid); } ); 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; } struct MultiThreadedUnique(T) { Tid currentOwner; Unique!T u; this(Unique!T u) { this.u = u.release(); this.currentOwner = thisTid; } void enforceRightOwner() { import std.exception; import std.string; enforce(currentOwner == thisTid, format("%s is the owner; not %s", currentOwner, thisTid)); } ref Unique!T get() { enforceRightOwner(); return u; } void giveTo(Tid newOwner) { enforceRightOwner(); currentOwner = newOwner; } } void main() { MultiThreadedUnique!S u1 = produce(); auto childTid2 = spawn(&spawnedFunc2, thisTid); u1.giveTo(childTid2); send(childTid2, cast(shared(MultiThreadedUnique!S*))&u1); import core.thread; thread_joinAll(); writeln("Successfully printed number."); auto u2 = &u1.get(); } Ali