[dmd-concurrency] Defining shared delegates
Steve Schveighoffer
schveiguy at yahoo.com
Tue Jan 19 11:43:32 PST 2010
----- Original Message ----
> From: Michel Fortin <michel.fortin at michelf.com>
> To: Discuss the concurrency model(s) for D <dmd-concurrency at puremagic.com>
> Sent: Tue, January 19, 2010 2:27:28 PM
> Subject: [dmd-concurrency] Defining shared delegates
>
> I think we should define a shared delegate as a delegate you can pass to other
> threads, and which other threads can call.
>
> The delegate contains a data pointer and a function pointer. The function's code
> is always immutable so there is never a problem sharing it. The data it carries
> can be part thread-local, part shared, part immutable. So here are the proposed
> rules:
>
> - If the data carried by the delegate is thread-local, in whole or in part,
> then the delegate is thread-local.
> - If the data is all shared or immutable, then the delegate can be shared.
>
> I believe all delegates should be shared when they refer only to immutable and
> shared data, and a shared delegate should implicitly convert to a thread-local
> delegate when necessary.
>
> Does it make sense that shared delegates convert implicitly to thread-local
> ones? This might look a little suspicious at first because you can't do that
> with other types, but with a delegate the data is private to only the associated
> code, and the associated code already knows whether the data is really shared or
> not, it is not relying on the caller's knowledge to call the right function like
> elsewhere. The result is that we can safely discard shared from the type the
> caller sees as it has no consequence.
>
> So this should be an error (and already is) because the delegate is accessing
> thread-local, mutable variables a and b:
>
> alias shared int delegate() SampleSharedDelegate;
>
> SampleSharedDelegate func1() {
> int a, b;
> return { return a + b; }; // error: cannot make delegate shared
> }
>
> This should work since a and b are shared:
>
> SampleSharedDelegate func2() {
> shared int a, b;
> return { return a + b; }; // ok, delegate can be shared
> }
>
> This too should work because a and b are immutable:
>
> SampleSharedDelegate func3() {
> immutable int a, b;
> return { return a + b; }; // ok, delegate can be shared
> }
>
> Does all this makes sense?
What about this?
SampleSharedDelegate func4() {
int x, y;
immutable int a, b;
return { return a + b; };
}
The stack frame contains both thread-local and immutable variables, but the delegate only accesses the immutable ones. Should this be allowed? A more explicit case:
class X
{
shared int a, b;
int x, y;
int foo() { return a + b; }
}
should foo be allowed to be a shared delegate? What if the compiler only can see the signature?
I think shared delegates should only be callable on shared classes/structs, or else you should have to mark the inner function shared:
SampleSharedDelegate func4()
{
shared int a, b;
int x, y;
shared int foo() { return a + b; }
//shared int foo2() { return x + y; } // fails to compile, shared inner function using unshared members of the stack frame.
int foo3() { return x + y; }
return &foo; // ok
return &foo3; // not ok, it was not marked as shared.
}
-Steve
More information about the dmd-concurrency
mailing list