Iterating over thread local storage variables

maik klein via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Mar 11 07:21:38 PST 2016


I want to create a logger in a multithreaded system. I wanted to 
expose a global variable like

logger.log("something");

I also wanted to reuse D's thread local global variables because 
that would make it easy to log in a multithreaded system.

This is really easy to do, but the problem is that at one point I 
need to collect all `loggers` and merge them.

So I thought about writing something like this:

import std.stdio;
class Singleton(T)
{
     import std.container: Array;
     private this() {}

     // Cache instantiation flag in thread-local bool
     // Thread local
     private static bool instantiated_;

     // Thread global
     private __gshared Singleton!T instance_;

     static Singleton!T get()
     {
         if (!instantiated_)
             {
             synchronized(Singleton!T.classinfo){
                 if (!instance_){
                     instance_ = new Singleton!T();
                 }
                 instantiated_ = true;
                 instance_.tls.insertBack(&instance_.value);
             }
         }

         return instance_;
     }
     __gshared Array!(T*) tls;
     static T value;
}
unittest{
     import std.concurrency;
     import core.thread;
     auto s = Singleton!int.get();
     foreach(index; 0..10){
         spawn((int a){
             auto s = Singleton!int.get();
             s.value = a;
         }, index);
     }
     Thread.sleep( dur!("seconds")( 1 ) );
     writeln("--");
     foreach(p; s.tls){
         writeln(*p);
     }
}

Basically every time `instantiated_` is false, I know that I am 
on a new thread and then I push the reference of `value` into a 
global array.

But how do I access `tls` in a thread safe manner?

Is there another way of doing this?



More information about the Digitalmars-d-learn mailing list