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