On Wed, 11 May 2011, Christian Heimes wrote:
Am 11.05.2011 19:03, schrieb Andi Vajda:
If these libraries use Python's Thread class you have some control.
Create a subclass of Thread that runs your hook and insert it into the
threading module (threading.Thread = YourThreadSubclass) before anyone else
gets a chance to create threads.
One library is using thread.start_new_thread() and another uses Python's
C API to create an internal monitor thread. This makes it even harder to
fix the issue.
If these functions eventually instantiate a Thread class, even indirectly,
the monkey-patching may still work.
How would you feel about another approach?
* factor out the attach routine of t_jccenv_attachCurrentThread() as C
function
int jccenv_attachCurrentThread(char *name, int asDaemon) {
JNIEnv *jenv = NULL;
JavaVMAttachArgs attach = {
JNI_VERSION_1_4, name, NULL
};
if (asDaemon)
result = env->vm->AttachCurrentThreadAsDaemon((void **) &jenv,
&attach);
else
result = env->vm->AttachCurrentThread((void **) &jenv, &attach);
env->set_vm_env(jenv);
return result;
}
* modify JCCEnv::deleteGlobalRef() to check get_vm_env() for NULL
if (iter->second.count == 1)
{
JNIEnv *vm_env = get_vm_env()
if (!vm_env) {
jccenv_attachCurrentThread(NULL, 0);
vm_env = get_vm_env();
}
vm_env->DeleteGlobalRef(iter->second.global);
refs.erase(iter);
}
That may cover this case but what about all the others ?
There is a reason the call has to be manual.
I've not been able to automate it before.
Over time, I've added checks where I could but I've not found it possible to
cover all cases where attachCurrentThread() wasn't called.
Anyhow, try it and see if it fixes the problem you're seeing.
If any of the objects being freed invoke user code that eventually call into
the JVM, the problem is going to appear again elsewhere.
Andi..