/*! * \brief Append new-class to container. * \param klassOop [in] New class oop. * \return New-class data. */ TObjectData *TClassContainer::pushNewClass(void *klassOop) { TObjectData *cur = NULL; /* Class info setting. */ cur = (TObjectData *)calloc(1, sizeof(TObjectData)); /* If failure allocate. */ if (unlikely(cur == NULL)) { /* Adding empty to list is deny. */ logger->printWarnMsg("Couldn't allocate counter memory!"); return NULL; } cur->tag = (uintptr_t)cur; cur->className = getClassName(getKlassFromKlassOop(klassOop)); /* If failure getting class name. */ if (unlikely(cur->className == NULL)) { /* Adding empty to list is deny. */ logger->printWarnMsg("Couldn't get class name!"); free(cur); return NULL; } cur->classNameLen = strlen(cur->className); cur->oopType = getClassType(cur->className); void *clsLoader = getClassLoader(klassOop, cur->oopType); TObjectData *clsLoaderData = NULL; /* If class loader isn't system bootstrap class loader. */ if (clsLoader != NULL) { void *clsLoaderKlsOop = getKlassOopFromOop(clsLoader); if (clsLoaderKlsOop != NULL) { /* Search classloader's class. */ clsLoaderData = this->findClass(clsLoaderKlsOop); if (unlikely(clsLoaderData == NULL)) { /* Register classloader's class. */ clsLoaderData = this->pushNewClass(clsLoaderKlsOop); } } } cur->clsLoaderTag = (clsLoaderData != NULL) ? clsLoaderData->tag : 0; cur->clsLoaderId = (uintptr_t)clsLoader; /* Chain setting. */ cur->klassOop = klassOop; TObjectData *result = this->pushNewClass(klassOop, cur); if (unlikely(result != cur)) { free(cur->className); free(cur); } return result; }
void onThreadDestruction() throw ( ::jace::JNIException ) { #ifdef _WIN32 if ( hasShutdown() ) return; JavaVM* jvm = getJavaVM(); ::jace::VmLoader* loader = getVmLoader(); jobject value = getClassLoader(); JNIEnv* env; // We must ensure that the thread is detached when we leave this function. bool mustDetachJVM = value != 0 || jvm->GetEnv( (void**) &env, loader->version() ) != JNI_EDETACHED; if ( mustDetachJVM ) { if ( value != 0 ) { setClassLoader( 0 ); } jace::helper::detach(); } #endif }
void setClassLoader(jobject classLoader) { JNIEnv* env = attach(); jobject oldRef = getClassLoader(); #ifdef SUPPORTS_PTHREADS int rc; #elif _WIN32 BOOL rc; #endif // Set the new value if ( classLoader != 0 ) { classLoader = static_cast<jobject> ( newGlobalRef( env, classLoader ) ); } #ifdef SUPPORTS_PTHREADS rc = pthread_setspecific( CLASSLOADER_KEY, classLoader ); if ( rc != 0 ) { std::string msg = "JNIHelper::setClassLoader()\n" "pthread_setspecific() returned " + std::to_string( rc ) + "."; throw JNIException( msg ); } #elif _WIN32 rc = TlsSetValue( CLASSLOADER_KEY, classLoader ); if ( !rc ) { std::string msg = "JNIHelper::setClassLoader()\n" "TlsSetValue() returned " + std::to_string( GetLastError() ) + "."; throw JNIException( msg ); } #endif // Delete the old value if necessary if ( oldRef != 0 ) { classLoaderDestructor( oldRef ); } }