Something needs to happen with shared, and soon.

Johannes Pfau nospam at example.com
Mon Nov 12 09:56:56 PST 2012


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


More information about the Digitalmars-d mailing list