Thread-safety and lazy-initialization of libraries

Sergey Protko via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 30 15:18:25 PDT 2014


On Monday, 30 June 2014 at 21:55:56 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
> On Mon, Jun 30, 2014 at 11:36:21PM +0200, Mike Wey via 
> Digitalmars-d-learn wrote:
>> On 06/30/2014 11:05 PM, bearophile wrote:
>> >Sergey Protko:
>> >
>> >>libmpg123 has mpg123_init and mpg123_exit functions, which 
>> >>are not
>> >>thread-safe, so we should to call them only once per 
>> >>process. Most
>> >>of useful libraries also has such stuff. But manual 
>> >>initialization
>> >>is killing all beauty of high-level bindings.
>> >
>> >I think module "static this" is thread-local, so in theory 
>> >you can
>> >use that. But I don't know if it's a good idea to perform 
>> >heavy
>> >computations inside those module static this.
>> >
>> >Bye,
>> >bearophile
>> 
>> You'll need to use a `shared static this` if those functions 
>> can be
>> called only once per process.
>> A regular static this is executed once per Thread.
> [...]
>
> Depending on how lazy you want initialization to be, you might 
> want to
> consider using __gshared (for process-global state) with 
> appropriate
> synchronization locks to make sure threads don't stomp over 
> each other.
> Then you can check if component X has been initialized (per 
> process)
> each time a thread calls some function that depends on X, and 
> if it is,
> initialize it, if not, just do nothing (or return the global 
> instance).
>
>
> T

Something like this?

module libmpg123;

__gshared bool initialized_;
static bool initializedTLS;

void init_requires()
{
     if (!initializedTLS) {
         synchronized {
             if (!initialized_) {
                 // todo: handle errors?
                 mpg123_init();
                 initialized_ = true;
             }
             initializedTLS = initialized_;
         }
     }
}

Well, i'll try... Thank you.


More information about the Digitalmars-d-learn mailing list