A little of coordination for Rosettacode

Stanislav Blinov stanislav.blinov at gmail.com
Wed Feb 26 04:37:34 PST 2014


On Wednesday, 26 February 2014 at 11:24:58 UTC, bearophile wrote:
> Ali Çehreli:

>>                synchronized {
>>                    // Switch to the next printer
>>                    printers = printers[1..$];
>>                }
>
> This doesn't work:
>
> printers.popFront();

Yes, because typeof(printers) == shared. I'm wondering why 
front() works.

>>            try {
>>                synchronized {
>>                    
>> (cast(Printer)printers.front).print(lines.front);
>>                }
>
> It it a good idea to define Printer.print like this to remove 
> that cast?
>
> void print(string line) shared

No it is not, because the implementation of print() would be 
invalid then:

     void print(string line) shared
     {
         enforce(ink != 0, new OutOfInk); // ink != 0 is not valid 
code
         writefln("%s: %s", id, line);
         --ink;                           // --ink is not valid 
code
     }

By declaring the method "shared" you promise that any acess to 
shared data in this method is safe. Using naked operators on 
shared scalar variables will eventually be disallowed, you'll 
have to explicitly use atomic operations.

You'd also have to synchronize access to id member, because it is 
public.  Although "immutable" means "implicitly shared", id being 
public means that potentionally one thread could be performing 
assigment to it while another one reads from it. Slices are two 
machine words, so atomicity of reads/writes is not implicitly 
guaranteed.

The cast in this case is safe and better approach because all 
access to "printers" is synchronized.
If/when https://d.puremagic.com/issues/show_bug.cgi?id=12133 and 
the corresponding pull is accepted, the cast could be replaced 
with

     printers.assumeLocal.front.print(lines.front);

which states the intent even more clearly, IMO.


More information about the Digitalmars-d-learn mailing list