shared methods

Benjamin Thaut code at benjamin-thaut.de
Wed Jan 22 02:08:11 PST 2014


Am 22.01.2014 06:16, schrieb unknown soldier:
> I'm confused by shared and how to use it.
>
> import std.stdio;
> class Foo {
>      File logFile;
>      void log(in string line) shared {
>        synchronized(this){
>          logFile.writeln(line);
>        }
>      }
> }
>
> This (or the equivalent code in my full size program) won't
> compile:
>
> source/log.d(256): Error: template std.stdio.File.writeln does
> not match any function template declaration. Candidates are:
> /usr/include/dmd/phobos/std/stdio.d(781):
> std.stdio.File.writeln(S...)(S args)
> source/log.d(256): Error: template std.stdio.File.writeln(S...)(S
> args) cannot deduce template function from argument types
> !()(const(immutable(char)[])) shared
>
> Why is logFile suddenly being treated as shared? This does not
> make sense to me. As a programmer I have acknowledged that log()
> is a shared function in the declaration 'void log(in string line)
> shared', so isn't it up to me to ensure that I do proper
> synchronization within the function? Why is the compiler trying
> to ensure that all functions called within log() are also marked
> shared?
> What is the right thing to do here?
>
> Note that I can't just mark log() as not shared; log() must be
> shared because elsewhere I have:
>
> shared Foo sfoo = ...
> sfoo.log(...)

For a shared method the this pointer is also shared. That means that you 
have to tell the compiler (manually) that it is now safe to use 
non-shared code. You usually do this by casting the this pointer to a 
unshared type.

class Foo {
      File logFile;
      void log(in string line) shared {
        synchronized(this){
          // safe from here on because synchronized
          auto self = cast(Foo)this;
          self.logFile.writeln(line);
        }
      }
}

The compiler does not do this for you, because it can not know if 
accessing any member is truly thread-safe. You might share the logFile 
with other instances of Foo. This would be a case where the compiler 
would wrongly remove the shared from this, if it would do so 
automatically inside synchronized blocks.




More information about the Digitalmars-d-learn mailing list