📄 threads.c.svn-base
字号:
* * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error */static xmlGlobalStatePtrxmlNewGlobalState(void){ xmlGlobalState *gs; gs = malloc(sizeof(xmlGlobalState)); if (gs == NULL) return(NULL); memset(gs, 0, sizeof(xmlGlobalState)); xmlInitializeGlobalState(gs); return (gs);}#endif /* LIBXML_THREAD_ENABLED */#ifdef HAVE_WIN32_THREADS#if !defined(HAVE_COMPILER_TLS)#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)typedef struct _xmlGlobalStateCleanupHelperParams{ HANDLE thread; void *memory;} xmlGlobalStateCleanupHelperParams;static void xmlGlobalStateCleanupHelper (void *p){ xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p; WaitForSingleObject(params->thread, INFINITE); CloseHandle(params->thread); xmlFreeGlobalState(params->memory); free(params); _endthread();}#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */typedef struct _xmlGlobalStateCleanupHelperParams{ void *memory; struct _xmlGlobalStateCleanupHelperParams * prev; struct _xmlGlobalStateCleanupHelperParams * next;} xmlGlobalStateCleanupHelperParams;static xmlGlobalStateCleanupHelperParams * cleanup_helpers_head = NULL;static CRITICAL_SECTION cleanup_helpers_cs;#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */#endif /* HAVE_COMPILER_TLS */#endif /* HAVE_WIN32_THREADS */#if defined HAVE_BEOS_THREADS/** * xmlGlobalStateCleanup: * @data: unused parameter * * Used for Beos only */void xmlGlobalStateCleanup(void *data){ void *globalval = tls_get(globalkey); if (globalval != NULL) xmlFreeGlobalState(globalval);}#endif/** * xmlGetGlobalState: * * xmlGetGlobalState() is called to retrieve the global state for a thread. * * Returns the thread global state or NULL in case of error */xmlGlobalStatePtrxmlGetGlobalState(void){#ifdef HAVE_PTHREAD_H xmlGlobalState *globalval; pthread_once(&once_control, xmlOnceInit); if ((globalval = (xmlGlobalState *) pthread_getspecific(globalkey)) == NULL) { xmlGlobalState *tsd = xmlNewGlobalState(); pthread_setspecific(globalkey, tsd); return (tsd); } return (globalval);#elif defined HAVE_WIN32_THREADS#if defined(HAVE_COMPILER_TLS) if (!tlstate_inited) { tlstate_inited = 1; xmlInitializeGlobalState(&tlstate); } return &tlstate;#else /* HAVE_COMPILER_TLS */ xmlGlobalState *globalval; xmlGlobalStateCleanupHelperParams * p; if (run_once_init) { run_once_init = 0; xmlOnceInit(); }#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) globalval = (xmlGlobalState *)TlsGetValue(globalkey);#else p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey); globalval = (xmlGlobalState *)(p ? p->memory : NULL);#endif if (globalval == NULL) { xmlGlobalState *tsd = xmlNewGlobalState(); p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams)); p->memory = tsd;#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS); TlsSetValue(globalkey, tsd); _beginthread(xmlGlobalStateCleanupHelper, 0, p);#else EnterCriticalSection(&cleanup_helpers_cs); if (cleanup_helpers_head != NULL) { cleanup_helpers_head->prev = p; } p->next = cleanup_helpers_head; p->prev = NULL; cleanup_helpers_head = p; TlsSetValue(globalkey, p); LeaveCriticalSection(&cleanup_helpers_cs); #endif return (tsd); } return (globalval);#endif /* HAVE_COMPILER_TLS */#elif defined HAVE_BEOS_THREADS xmlGlobalState *globalval; xmlOnceInit(); if ((globalval = (xmlGlobalState *) tls_get(globalkey)) == NULL) { xmlGlobalState *tsd = xmlNewGlobalState(); tls_set(globalkey, tsd); on_exit_thread(xmlGlobalStateCleanup, NULL); return (tsd); } return (globalval);#else return(NULL);#endif}/************************************************************************ * * * Library wide thread interfaces * * * ************************************************************************//** * xmlGetThreadId: * * xmlGetThreadId() find the current thread ID number * * Returns the current thread ID number */intxmlGetThreadId(void){#ifdef HAVE_PTHREAD_H return((int) pthread_self());#elif defined HAVE_WIN32_THREADS return GetCurrentThreadId();#elif defined HAVE_BEOS_THREADS return find_thread(NULL);#else return((int) 0);#endif}/** * xmlIsMainThread: * * xmlIsMainThread() check whether the current thread is the main thread. * * Returns 1 if the current thread is the main thread, 0 otherwise */intxmlIsMainThread(void){#ifdef HAVE_PTHREAD_H pthread_once(&once_control, xmlOnceInit);#elif defined HAVE_WIN32_THREADS if (run_once_init) { run_once_init = 0; xmlOnceInit (); }#elif defined HAVE_BEOS_THREADS xmlOnceInit();#endif #ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");#endif#ifdef HAVE_PTHREAD_H return(mainthread == pthread_self());#elif defined HAVE_WIN32_THREADS return(mainthread == GetCurrentThreadId ());#elif defined HAVE_BEOS_THREADS return(mainthread == find_thread(NULL));#else return(1);#endif}/** * xmlLockLibrary: * * xmlLockLibrary() is used to take out a re-entrant lock on the libxml2 * library. */voidxmlLockLibrary(void){#ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");#endif xmlRMutexLock(xmlLibraryLock);}/** * xmlUnlockLibrary: * * xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2 * library. */voidxmlUnlockLibrary(void){#ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");#endif xmlRMutexUnlock(xmlLibraryLock);}/** * xmlInitThreads: * * xmlInitThreads() is used to to initialize all the thread related * data of the libxml2 library. */voidxmlInitThreads(void){#ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");#endif#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) InitializeCriticalSection(&cleanup_helpers_cs);#endif}/** * xmlCleanupThreads: * * xmlCleanupThreads() is used to to cleanup all the thread related * data of the libxml2 library once processing has ended. */voidxmlCleanupThreads(void){#ifdef DEBUG_THREADS xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");#endif#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) if (globalkey != TLS_OUT_OF_INDEXES) { xmlGlobalStateCleanupHelperParams * p; EnterCriticalSection(&cleanup_helpers_cs); p = cleanup_helpers_head; while (p != NULL) { xmlGlobalStateCleanupHelperParams * temp = p; p = p->next; xmlFreeGlobalState(temp->memory); free(temp); } cleanup_helpers_head = 0; LeaveCriticalSection(&cleanup_helpers_cs); TlsFree(globalkey); globalkey = TLS_OUT_OF_INDEXES; } DeleteCriticalSection(&cleanup_helpers_cs);#endif}#ifdef LIBXML_THREAD_ENABLED/** * xmlOnceInit * * xmlOnceInit() is used to initialize the value of mainthread for use * in other routines. This function should only be called using * pthread_once() in association with the once_control variable to ensure * that the function is only called once. See man pthread_once for more * details. */static voidxmlOnceInit(void) {#ifdef HAVE_PTHREAD_H (void) pthread_key_create(&globalkey, xmlFreeGlobalState); mainthread = pthread_self();#endif#if defined(HAVE_WIN32_THREADS)#if !defined(HAVE_COMPILER_TLS) globalkey = TlsAlloc();#endif mainthread = GetCurrentThreadId();#endif#ifdef HAVE_BEOS_THREADS if (atomic_add(&run_once_init, 1) == 0) { globalkey = tls_allocate(); tls_set(globalkey, NULL); mainthread = find_thread(NULL); } else atomic_add(&run_once_init, -1);#endif}#endif/** * DllMain: * @hinstDLL: handle to DLL instance * @fdwReason: Reason code for entry * @lpvReserved: generic pointer (depends upon reason code) * * Entry point for Windows library. It is being used to free thread-specific * storage. * * Returns TRUE always */#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))#if defined(LIBXML_STATIC_FOR_DLL)BOOL WINAPI xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) #elseBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) #endif{ switch(fdwReason) { case DLL_THREAD_DETACH: if (globalkey != TLS_OUT_OF_INDEXES) { xmlGlobalState *globalval = NULL; xmlGlobalStateCleanupHelperParams * p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey); globalval = (xmlGlobalState *)(p ? p->memory : NULL); if (globalval) { xmlFreeGlobalState(globalval); TlsSetValue(globalkey,NULL); } if (p) { EnterCriticalSection(&cleanup_helpers_cs); if (p == cleanup_helpers_head) cleanup_helpers_head = p->next; else p->prev->next = p->next; if (p->next != NULL) p->next->prev = p->prev; LeaveCriticalSection(&cleanup_helpers_cs); free(p); } } break; } return TRUE;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -