/** * Adds JVM to the list unless it's already there. If JVM is not added to * the list, it gets deallocated. */ STATIC Bool JVM_Add(JVMSet * jvms, JVM * jvm) { if (jvm) { int pos = VECTOR_IndexOf(&jvms->found, jvm); if (pos < 0) { return VECTOR_TryAdd(&jvms->found, jvm); } else { /* if the new JVM has better flags, replace the old one */ Bool replace = False; JVM * jvm2 = VECTOR_Get(&jvms->found, pos); if (!(jvm2->flags & JVM_FLAG_SPECIAL) && (jvm->flags & JVM_FLAG_SPECIAL)) { /* copy version information from the existing JRE */ Char * tmp = jvm->versionString; jvm->version = jvm2->version; jvm->nVersionDigits = jvm2->nVersionDigits; jvm->versionString = jvm2->versionString; jvm2->versionString = tmp; replace = True; } else if ((jvm2->flags & JVM_FLAG_JDK) && !(jvm->flags & JVM_FLAG_JDK)) { /* we prefer JRE over JDK */ replace = True; } else if (!(jvm2->flags & JVM_FLAG_DEFAULT) && (jvm->flags & JVM_FLAG_DEFAULT)) { /* new JVM is the default one */ replace = True; } if (replace) { if (jvm2->nVersionDigits > jvm->nVersionDigits) { /* existing JVM has more detailed version information */ Char * tmp = jvm->versionString; jvm->version = jvm2->version; jvm->nVersionDigits = jvm2->nVersionDigits; jvm->versionString = jvm2->versionString; jvm2->versionString = tmp; } TRACE1("JNILIB: duplicate JVM %s\n",jvm->versionString); VECTOR_Set(&jvms->found, pos, jvm); return True; } else { if (jvm->nVersionDigits > jvm2->nVersionDigits) { /* new JVM has more detailed version information */ Char * tmp = jvm2->versionString; jvm2->version = jvm->version; jvm2->nVersionDigits = jvm->nVersionDigits; jvm2->versionString = jvm->versionString; jvm->versionString = tmp; } TRACE1("JNILIB: duplicate JVM %s\n",jvm2->versionString); JVM_Free(jvm); } } } return False; }
/** * Destroys thread local variables, sets exit event and dereferences * the thread handle. */ STATIC void THREAD_Cleanup(ThrData* thr) { /* invoke destructors for thread local variables */ int i, n = 1; for (i=0; i<MAX_DESTRUCTOR_ITERATIONS && n > 0; i++) { int k; n = 0; for (k=0; k<VECTOR_Size(&thr->cleanupList); k++) { ThrKey key = VECTOR_Get(&thr->cleanupList, k); void * value = TlsGetValue(key->index); if (value) { TlsSetValue(key->index, NULL); #ifdef _USE_EXCEPTION_HANDLING __try { #endif /* _USE_EXCEPTION_HANDLING */ key->clean(value); ASSERT(!TlsGetValue(key->index)); #ifdef _USE_EXCEPTION_HANDLING } __except(EXCEPTION_EXECUTE_HANDLER) { TlsSetValue(key->index,NULL); ASSMSG1("EXCEPTION %08lX in cleanup proc!", GetExceptionCode()); } #endif /* _USE_EXCEPTION_HANDLING */ n++; } } } ASSERT(i<MAX_DESTRUCTOR_ITERATIONS); /* Dereference ThrKey structures */ while ((n = VECTOR_Size(&thr->cleanupList)) > 0) { ThrKey key = VECTOR_Remove(&thr->cleanupList, n-1); if (InterlockedDecrement(&key->ref) == 0) { ASSERT(key->index == TLS_OUT_OF_INDEXES); MEM_Free(key); } } InterlockedDecrement(&WIN32_ThreadCount); VECTOR_Destroy(&thr->cleanupList); EVENT_Set(&thr->exitEvent); THREAD_Deref(thr); }
/** * Character handler for XML_Handle. Passes the data to the current * element handler. */ STATIC void XML_HandleCharData(void * ctx, const wchar_t * s, int len) { XMLContext * context = (XMLContext*)ctx; int depth = VECTOR_Size(&context->stack); ASSERT(depth > 0); if (depth > 0 && !context->error) { XMLTagCtx * tagContext; tagContext = (XMLTagCtx*)VECTOR_Get(&context->stack,depth-1); ASSERT(tagContext && tagContext->context == context); /* * if the handler does not expect any character data, we ignore those * characters, although it might be considered an error... */ if (tagContext->tag->handleChars) { if (!tagContext->tag->handleChars(tagContext->tag, s, len)) { context->error = True; } } } }
/** * "End element" callback for XML_Handle. If this tag has been "skipped" by * XML_StartElemCB, simply decrements skipDepth. Otherwise, calls the client * callback to deallocate the tag context. */ STATIC void XML_HandleEndElem(void * ctx, Str tag) { XMLContext * context = (XMLContext*)ctx; UNREF(tag); if (context->error && context->skipDepth > 0) { context->skipDepth--; } else { int depth = VECTOR_Size(&context->stack); ASSERT(depth > 0); if (depth == 1 && !context->error) { XMLTagCtx * root; root = (XMLTagCtx*)VECTOR_Get(&context->stack,0); ASSERT(root && root->context == context); ASSERT(!context->rootTag); /* prevent XML_VectorFreeTagContext from deallocating the tag */ context->rootTag = root->tag; root->tag = NULL; } if (depth > 0) { VECTOR_Remove(&context->stack, depth-1); } } }
/** * "Start element" callback for XML_Handle. Creates new entry in the element * stack. If an error has occured, simply increments skipDepth */ STATIC void XML_HandleStartElem(void * ctx, Str tag, const XMLAttr * a) { XMLContext * context = (XMLContext*)ctx; if (context->error) { context->skipDepth++; } else { XMLTag * t = NULL; int depth = VECTOR_Size(&context->stack); if (!depth) { /* this is a root element */ if (!context->rootTagName || !StrCmp(tag, context->rootTagName)) { /* we don't expect more than one root tag */ ASSERT(!context->rootTag); if (!context->rootTag) { t = context->rootHandler(context->rootContext, tag, a); } } else { Warning(TEXT("WARNING: invalid root tag <%s>, expected <%s>\n"), tag, context->rootTagName); } } else { XMLTagCtx * parent; parent = (XMLTagCtx*)VECTOR_Get(&context->stack, depth-1); ASSERT(parent && parent->tag && parent->context == context); /* * if tag handler is NULL, it means that the handler for the * parent tag didn't expect any inner tags; we treat this as * an error */ if (parent->tag->handleTag) { t = parent->tag->handleTag(parent->tag, tag, a); } } if (t) { /* add new tag to the stack */ XMLTagCtx * tagContext = MEM_New(XMLTagCtx); XMLTag * p = NULL; if (depth > 0) { p = ((XMLTagCtx*)VECTOR_Get(&context->stack,depth-1))->tag; } if (tagContext) { memset(tagContext, 0, sizeof(*tagContext)); tagContext->context = context; tagContext->tag = t; tagContext->parent = p; if (VECTOR_Add(&context->stack, tagContext)) { return; } MEM_Free(tagContext); } XML_FreeTag(t, p); } /* handle error */ context->error = True; context->skipDepth++; } }
/** * Returns i-th discovered JVM. By default, JVMs are sorted by version, * i.e. the first JVM in the list has the most recent version. */ JVM * JVM_Get(JVMSet * jvms, int i) { return (JVM *)VECTOR_Get(&jvms->found, i); }