Created
July 31, 2011 05:34
-
-
Save eatnumber1/1116445 to your computer and use it in GitHub Desktop.
D Runtime Initialization Routine Wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import core.atomic; | |
import core.runtime; | |
import core.sync.mutex; | |
version( Windows ) { | |
import core.stdc.stdlib; | |
} else version( Posix ) { | |
import core.sys.posix.stdlib; | |
} else { | |
static assert(false, "Unknown platform"); | |
} | |
shared int calls = 0; | |
shared Mutex initLock = null; | |
private Mutex newLock() { | |
auto ci = Mutex.classinfo; | |
auto ptr = malloc(ci.init.length); | |
if( ptr is null ) return null; | |
(cast(byte*) ptr)[0..ci.init.length] = ci.init[]; | |
auto mutex = cast(Mutex) ptr; | |
mutex.__ctor(); | |
return mutex; | |
} | |
private void freeLock( Mutex lock ) { | |
lock.__dtor(); | |
free(cast(void *) lock); | |
} | |
extern (C) { | |
bool init() { | |
Mutex mutex = newLock(); | |
if( mutex is null ) return false; | |
if( initLock is null ) { | |
initLock = cast(shared) mutex; | |
} else | |
// This is necessary for proper operation, but I can't get it to compile... | |
//if( !cas(cast(shared(const(Mutex)*)) &initLock, cast(const) null, cast(const) mutex) ) | |
freeLock(cast(Mutex) initLock); | |
bool ret; | |
synchronized( initLock ) { | |
ret = calls == 0 ? Runtime.initialize() : true; | |
calls++; | |
} | |
return ret; | |
} | |
bool terminate() { | |
assert(initLock !is null); | |
assert(calls >= 0); | |
bool destroyLock = false, ret; | |
synchronized( initLock ) { | |
if( calls == 0 ) { | |
ret = Runtime.terminate(); | |
destroyLock = true; | |
} else { | |
ret = true; | |
} | |
calls--; | |
} | |
if( destroyLock ) freeLock(cast(Mutex) initLock); | |
return ret; | |
} | |
bool init2() { | |
return atomicOp!"+="(calls, 1) == 1 ? Runtime.initialize() : true; | |
} | |
bool terminate2() { | |
return atomicOp!"-="(calls, 1) == 0 ? Runtime.terminate() : true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment