On Saturday, 19 May 2012 at 21:13:14 UTC, japplegame wrote:
You don't need to mark Tids as shared.
Okay. I'm writting logger. Logger is global object and it is
running in its own separate thread (for example, writting logs to
remote database).
My application has several threads and all of them want to log
something. How to share this global logger between threads? I
think the simplest way is to share logger's thread tid and other
thread can send logs via this shared tid.

public:
void startLogger(LogConstructorArgs args) {
    loggerTid = spawn(&loggerThread, args);
}

void log(string msg, OtherOptions oo) {
    loggerTid.send(LogMsg(msg, oo));
}

void stopLogger() {
    loggerTid.send(QuitMsg());
}

private:
Tid loggerTid;

struct LogMsg {
    string msg;
    OtherOptions oo;
}

struct QuitMsg {}

void loggerThread(LogConstructorArgs args) {
    Logger lg = new Logger(args);
    bool cont = true;
    while(cont) {
        receive((LogMsg lm) { lg.log(lm.msg, lm.oo); },
                (QuitMsg qm) { cont = false; });
    }
}

If you originally create it as shared, you don't need to do the casting.
Yes. I don't need to cast to shared, but inside thread I get
shared object and can't store/call/pass it without casting away
that shared attribute. Or I should make shared everyting that
have deal with shared object.
I'am trying to follow Safe D concept, but it forbids casting away
shared.

If you are passing objects between threads, make it shared. This might seem annoying, but in general you should try to shift your thinking into having thread-local objects and communicating via structs.

But when you use global/singleton objects (any case where there's one instance of the class), convert it into a thread, FROM

class <name> {
    this(<cons args>) {
        <constructor>
    }

    void <method1>() {
        // ...
    }

    int <method2>() {
        int result;
        // ...
        return result;
    }

<private fields> // you encapsulate and have no public fields, right?
}

TO

void <name>Thread(<cons args>) {
    <private fields>
    <constructor>
    bool cont = true;
    while(cont) {
        receive(
            (<method1>Msg) {
                // ...
            },
            (Tid r, <method2>Msg) {
                int result;
                // ...
                r.send(<method2>ReturnMsg(result));
            }
            (QuitMsg qm) {cont = false;});
    }
}

Reply via email to