コード例 #1
0
ファイル: w_thread.c プロジェクト: jhanulis7/HAL
/**
 * 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);
}
コード例 #2
0
ファイル: s_xmlp.c プロジェクト: fedor4ever/packaging
/*
 * XML_Handle parses well-formed XML stream returning the root tag context
 * on success, NULL on failure. The endTag callback provided by the root tag
 * handler can be used to deallocate the root tag can context without any
 * side effects. However, in order to extract any useful information from the 
 * root tag context, each object providing root tag handler would normally
 * provide a function that would exract such information from the root tag 
 * (and deallocate everything else).
 *
 * The last parameter is a context parameter passed to the root tag callback
 * as the first argument. The code calling XML_Handle or the XMLHandleRoot
 * callback directly must know that XMLHandleRoot expects as a context
 * parameter. Typically, this is not a problem, but the use of this parameter
 * is discouraged. The XML stream should be self-sufficient, i.e. it should
 * contain all the information necessary to completely parse it. The context
 * parameter exists primarily to support for legacy XML file formats that 
 * require extra parsing information in addition to the information contained
 * in the XML stream itself.
 */
XMLTag * XML_Handle(File * f, Str tag, XMLHandleRoot root, void * ctx)
{
    XMLTag * rootTag = NULL;
    XMLContext context;
    memset(&context, 0, sizeof(context));
    context.rootTagName = tag;
    context.rootHandler = root;
    context.rootContext = ctx;
    if (VECTOR_Init(&context.stack, 0, NULL, XML_VectorFreeTagContext)) {
        XMLCallbacks cb;
        memset(&cb, 0, sizeof(cb));
        cb.startElem = XML_HandleStartElem;
        cb.endElem = XML_HandleEndElem;
        cb.charData = XML_HandleCharData;
        if (!XML_ParseStream(f, &cb, &context)) {
            context.error = True;
        }
        if (!context.error) {
            rootTag = context.rootTag;
        } else if (context.rootTag) {
            if (context.rootTag->endTag) {
                context.rootTag->endTag(context.rootTag, NULL);
            } else {
                MEM_Free(context.rootTag);
            }
        }

        /* 
         * VECTOR_Destroy would destroy the elements starting with the
         * first element. We must start with the last element, which is
         * a natural cleanup order for a stack. If parsing was successful,
         * the vector is already empty. However, if parsing failed, the
         * vector may be non-empty and the order in which we deallocate the
         * tags must be opposite to the order in which they were created.
         */
        while (!VECTOR_IsEmpty(&context.stack)) {
            VECTOR_Remove(&context.stack, VECTOR_Size(&context.stack)-1);
        }
        VECTOR_Destroy(&context.stack);
    }
    return rootTag;
}
コード例 #3
0
ファイル: s_xmlp.c プロジェクト: fedor4ever/packaging
/**
 * "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);
        }
    }
}