On Monday, 12 November 2012 at 11:19:57 UTC, Walter Bright wrote:
On 11/12/2012 2:57 AM, Johannes Pfau wrote:
But there are also shared member functions and they're kind of annoying
right now:

* You can't call shared methods from non-shared methods or vice versa. This leads to code duplication, you basically have to implement
  everything twice:

You can't get away from the fact that data that can be accessed from multiple threads has to be dealt with in a *fundamentally* different way than single threaded code. You cannot share code between the two. There is simply no conceivable way that "share" can be added and then code will become thread safe.

I know share can't automatically make the code thread safe. I
just wanted to point out that this casting / code duplication is
annoying but I don't know either how this could be solved.



Yes, mutexes will need to exist in a global space.

I'm not sure if I undestand this. Don't you think shared(Mutex)
should work?
AFAICS that's only a library problem: Add shared to the lock /
unlock methods in druntime and it should work?

Or global as in not in the struct instance?



And then there are some open questions with advanced use cases:
* How do I make sure that a non-shared delegate is only accepted if I
  have an A, but a shared delegate should be supported
for shared(A) and A? (calling a shared delegate from a non-shared
  function should work, right?)

struct A
{
    void a(T)(T v)
    {
        writeln("non-shared");
    }
shared void a(T)(T v) if (isShared!v) //isShared doesn't exist
    {
        writeln("shared");
    }
}

First, you have to decide what you mean by a shared delegate. Do you mean the variable containing the two pointers that make up a delegate are shared, or the delegate is supposed to deal with shared data?

I'm talking about a delegate pointing to a method declared with
the "shared" keyword and the "this pointer" pointing to a shared
object:
struct A
{
    shared void a(){}
}
shared A instance;
auto del = &instance.a; //I'm talking about this type

To explain that usecase: I think of a shared delegate as a
delegate that can be safely called from different threads. So I
can store it in a struct instance and later on call it from any
thread:

struct Signal
{
     //The variable is shared _AND_ the method is shared
     shared(shared void delegate()) _handler;

     shared void call() //Can be called from any thread
     {
         //Would have to synchronize access to the variable in a
real world case,
         //but the call itself wouldn't have to be synchronized
         shared void delegate() localHandler;
         synchronized(mutex)
         {
             localHandler = _handler;
         }
         localHandler ();
     }
}




And having fun with this little example:
http://dpaste.dzfl.pl/7f6a4ad2

* What's the difference between: "void delegate() shared"
  and "shared(void delegate())"?

Error: cannot implicitly convert expression (&a.abc) of type void
delegate() shared

The delegate deals with shared data.

OK so that's what I need but the compiler doesn't let me declare
that type.

alias void delegate() shared del;
Error: const/immutable/shared/inout attributes are only valid for
non-static member functions

to shared(void delegate())

The variable holding the delegate is shared.

OK, but when it's used as a function parameter, which is
pass-by-value for delegates and because of tail-shared there's
effectively no difference, right? In that case it's not possible
to pass a shared variable to the function as this will always
create a copy?

void abcd(shared(void delegate()) del)
which is the same as
void abcd(shared void delegate() del)

How would you pass del as a shared variable?



* So let's call it void delegate() shared instead:
void incrementA(void delegate() shared del)
/home/c684/c922.d(7): Error: const/immutable/shared/inout attributes
  are only valid for non-static member functions

Reply via email to