Can I use Schwarz counter (aka Nifty counter) idiom, with thread_local
? (Assuming I replace all static
with thread_local
)
I need this (helper for java jni threads):
class ThisThread{
JNIEnv* jni_env{nullptr};
public:
JNIEnv* getEnv(){
if (!jni_env){
// Attach thread
java_vm->GetEnv((void**)&jni_env, JNI_VERSION);
java_vm->AttachCurrentThread(&jni_env, NULL);
}
return jni_env;
}
~ThisThread(){
if (!jni_env) return;
// Deattach thread
java_vm->DetachCurrentThread();
}
};
static thread_local ThisThread this_thread;
To be constructed first, and destructed last in each thread.
I may call this_thread->getEnv()
from destructor/constructor of other static or thread_local object.
UPDATE
https://stackoverflow.com/a/30200992 - here, standard says that thread_local destructors called BEFORE static, and I need this one to be after.
I think the best solution is to implement the schwartz counter as normal, but implement the
ThisThread
class in terms of athread_local
staticImpl
.Complete example with outputs:
example output:
This does not answer how to make Schwarz counter for
thread_local static
's (so I don't accept this as answer). But in the end, I came up with this platform-dependent(Linux/Android) solution.Even if by some reason,
pthread_dstr
will be called before C++'s static thread_locals (or interleaved) [in other wordsThisThread
destroyed before last use], on next call to object (getEnv()
) we kinda re-init/re-create it and registerpthread_dstr
for another round.N.B. At total maximum we can have
PTHREAD_DESTRUCTOR_ITERATIONS
rounds, which is 4. But we always will end up on a second one, at worst case (if C++ thread_local implementation will use p_thread destructors [which will mean that OURpthread_dstr
may not be called last in the first round]).