On 02/25/2014 03:48 PM, bearophile wrote:
Is someone willing to write a D entry for this?

http://rosettacode.org/wiki/Rendezvous

Bye,
bearophile

I think the following satisfies the requirements. Improve at will! :p

import std.stdio;
import std.exception;
import std.array;
import std.concurrency;
import std.datetime;
import core.thread;

class OutOfInk : Exception
{
    this()
    {
        super("Out of ink.");
    }
}

struct Printer
{
    string id;
    size_t ink;

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

struct PrinterRendezvous
{
    Printer[] printers;

    void print(string[] lines) shared
    {
        Exception savedException;

        while (true) {
            if (lines.empty) {
                break;
            }

            if (printers.empty) {
                // No more printers to try
                assert(savedException !is null);
                throw savedException;
            }

            try {
                synchronized {
                    (cast(Printer)printers.front).print(lines.front);
                }
                lines.popFront();

                // Increase the chance of interleaved output
                Thread.sleep(10.msecs);

            } catch (OutOfInk exc) {
                savedException = exc;

                synchronized {
                    // Switch to the next printer
                    printers = printers[1..$];
                }
            }
        }
    }
}

void humptyDumptyTask(ref shared(PrinterRendezvous) rendezvous)
{
    auto humptyDumpty = [ "Humpty Dumpty sat on a wall.",
                          "Humpty Dumpty had a great fall.",
                          "All the king's horses and all the king's men,",
                          "Couldn't put Humpty together again.", ];

    rendezvous.print(humptyDumpty);
}

void motherGooseTask(ref shared(PrinterRendezvous) rendezvous)
{
    auto motherGoose = [ "Old Mother Goose,",
                         "When she wanted to wander,",
                         "Would ride through the air,",
                         "On a very fine gander.",
                         "Jack's mother came in,",
                         "And caught the goose soon,",
                         "And mounting its back,",
                         "Flew up to the moon.", ];

    rendezvous.print(motherGoose);
}

void main()
{
    auto rendezvous = shared(PrinterRendezvous)([ Printer("main", 5),
                                                  Printer("reserve", 5) ]);

    spawn(&humptyDumptyTask, rendezvous);
    spawn(&motherGooseTask, rendezvous);
}

Sample output:

main: Humpty Dumpty sat on a wall.
main: Old Mother Goose,
main: Humpty Dumpty had a great fall.
main: When she wanted to wander,
main: All the king's horses and all the king's men,
reserve: Would ride through the air,
reserve: Couldn't put Humpty together again.
reserve: On a very fine gander.
reserve: Jack's mother came in,
reserve: And caught the goose soon,
deneme.OutOfInk@deneme.d([...]): Out of ink.

Ali

Reply via email to