mirror of
				https://gitlab.gnome.org/GNOME/libxml2.git
				synced 2025-10-31 21:50:33 +03:00 
			
		
		
		
	threads: Rework initialization
Make init/cleanup functions private. Merge xmlOnceInit into xmlInitThreadsInternal.
This commit is contained in:
		| @@ -5,4 +5,7 @@ void __xmlGlobalInitMutexLock(void); | ||||
| void __xmlGlobalInitMutexUnlock(void); | ||||
| void __xmlGlobalInitMutexDestroy(void); | ||||
|  | ||||
| void xmlInitThreadsInternal(void); | ||||
| void xmlCleanupThreadsInternal(void); | ||||
|  | ||||
| #endif /* XML_THREADS_H_PRIVATE__ */ | ||||
|   | ||||
							
								
								
									
										4
									
								
								parser.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								parser.c
									
									
									
									
									
								
							| @@ -14495,7 +14495,7 @@ xmlInitParser(void) { | ||||
|     __xmlGlobalInitMutexLock(); | ||||
|     if (xmlParserInitialized == 0) { | ||||
| #endif | ||||
| 	xmlInitThreads(); | ||||
| 	xmlInitThreadsInternal(); | ||||
| 	xmlInitGlobalsInternal(); | ||||
| 	xmlInitMemoryInternal(); | ||||
|         xmlInitializeDict(); | ||||
| @@ -14555,7 +14555,7 @@ xmlCleanupParser(void) { | ||||
|     xmlRelaxNGCleanupTypes(); | ||||
| #endif | ||||
|     xmlCleanupGlobalsInternal(); | ||||
|     xmlCleanupThreads(); /* must be last if called not from the main thread */ | ||||
|     xmlCleanupThreadsInternal(); | ||||
|     xmlCleanupMemoryInternal(); | ||||
|     xmlParserInitialized = 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										122
									
								
								threads.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								threads.c
									
									
									
									
									
								
							| @@ -47,7 +47,6 @@ static int libxml_is_threaded = -1; | ||||
|  | ||||
| #define XML_PTHREAD_WEAK | ||||
|  | ||||
| #pragma weak pthread_once | ||||
| #pragma weak pthread_getspecific | ||||
| #pragma weak pthread_setspecific | ||||
| #pragma weak pthread_key_create | ||||
| @@ -118,8 +117,6 @@ struct _xmlRMutex { | ||||
| #ifdef HAVE_POSIX_THREADS | ||||
| static pthread_key_t globalkey; | ||||
| static pthread_t mainthread; | ||||
| static pthread_once_t once_control = PTHREAD_ONCE_INIT; | ||||
| static pthread_once_t once_control_init = PTHREAD_ONCE_INIT; | ||||
| static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER; | ||||
| #elif defined HAVE_WIN32_THREADS | ||||
| #if defined(HAVE_COMPILER_TLS) | ||||
| @@ -129,19 +126,11 @@ static __declspec(thread) int tlstate_inited = 0; | ||||
| static DWORD globalkey = TLS_OUT_OF_INDEXES; | ||||
| #endif /* HAVE_COMPILER_TLS */ | ||||
| static DWORD mainthread; | ||||
| static struct { | ||||
|     DWORD done; | ||||
|     LONG control; | ||||
| } run_once = { 0, 0}; | ||||
| static volatile LPCRITICAL_SECTION global_init_lock = NULL; | ||||
| #endif | ||||
|  | ||||
| static xmlRMutexPtr xmlLibraryLock = NULL; | ||||
|  | ||||
| #ifdef LIBXML_THREAD_ENABLED | ||||
| static void xmlOnceInit(void); | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * xmlNewMutex: | ||||
|  * | ||||
| @@ -538,8 +527,6 @@ xmlGetGlobalState(void) | ||||
|     if (libxml_is_threaded == 0) | ||||
|         return (NULL); | ||||
|  | ||||
|     pthread_once(&once_control, xmlOnceInit); | ||||
|  | ||||
|     if ((globalval = (xmlGlobalState *) | ||||
|          pthread_getspecific(globalkey)) == NULL) { | ||||
|         xmlGlobalState *tsd = xmlNewGlobalState(); | ||||
| @@ -560,8 +547,6 @@ xmlGetGlobalState(void) | ||||
| #else /* HAVE_COMPILER_TLS */ | ||||
|     xmlGlobalState *globalval; | ||||
|     xmlGlobalStateCleanupHelperParams *p; | ||||
|  | ||||
|     xmlOnceInit(); | ||||
| #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) | ||||
|     globalval = (xmlGlobalState *) TlsGetValue(globalkey); | ||||
| #else | ||||
| @@ -654,14 +639,10 @@ xmlGetThreadId(void) | ||||
| int | ||||
| xmlIsMainThread(void) | ||||
| { | ||||
|     xmlInitParser(); | ||||
| #ifdef HAVE_POSIX_THREADS | ||||
|     if (libxml_is_threaded == -1) | ||||
|         xmlInitThreads(); | ||||
|     if (libxml_is_threaded == 0) | ||||
|         return (1); | ||||
|     pthread_once(&once_control, xmlOnceInit); | ||||
| #elif defined HAVE_WIN32_THREADS | ||||
|     xmlOnceInit(); | ||||
| #endif | ||||
|  | ||||
| #ifdef DEBUG_THREADS | ||||
| @@ -709,20 +690,26 @@ xmlUnlockLibrary(void) | ||||
| /** | ||||
|  * xmlInitThreads: | ||||
|  * | ||||
|  * DEPRECATED: This function will be made private. Call xmlInitParser to | ||||
|  * initialize the library. | ||||
|  * | ||||
|  * xmlInitThreads() is used to to initialize all the thread related | ||||
|  * data of the libxml2 library. | ||||
|  * DEPRECATED: Alias for xmlInitParser. | ||||
|  */ | ||||
| void | ||||
| xmlInitThreads(void) | ||||
| { | ||||
|     xmlInitParser(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * xmlInitThreadsInternal: | ||||
|  * | ||||
|  * Used to to initialize all the thread related data. | ||||
|  */ | ||||
| void | ||||
| xmlInitThreadsInternal(void) | ||||
| { | ||||
| #ifdef HAVE_POSIX_THREADS | ||||
| #ifdef XML_PTHREAD_WEAK | ||||
|     if (libxml_is_threaded == -1) { | ||||
|         if ((pthread_once != NULL) && | ||||
|             (pthread_getspecific != NULL) && | ||||
|         if ((pthread_getspecific != NULL) && | ||||
|             (pthread_setspecific != NULL) && | ||||
|             (pthread_key_create != NULL) && | ||||
|             (pthread_key_delete != NULL) && | ||||
| @@ -750,38 +737,42 @@ xmlInitThreads(void) | ||||
|         } | ||||
|     } | ||||
| #endif /* XML_PTHREAD_WEAK */ | ||||
|     pthread_key_create(&globalkey, xmlFreeGlobalState); | ||||
|     mainthread = pthread_self(); | ||||
| #elif defined(HAVE_WIN32_THREADS) | ||||
| #if !defined(HAVE_COMPILER_TLS) | ||||
| #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) | ||||
|     InitializeCriticalSection(&cleanup_helpers_cs); | ||||
| #endif | ||||
|     globalkey = TlsAlloc(); | ||||
| #endif | ||||
|     mainthread = GetCurrentThreadId(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * xmlCleanupThreads: | ||||
|  * | ||||
|  * DEPRECATED: This function will be made private. Call xmlCleanupParser | ||||
|  * DEPRECATED: This function is a no-op. Call xmlCleanupParser | ||||
|  * to free global state but see the warnings there. xmlCleanupParser | ||||
|  * should be only called once at program exit. In most cases, you don't | ||||
|  * have call cleanup functions at all. | ||||
|  * | ||||
|  * xmlCleanupThreads() is used to to cleanup all the thread related | ||||
|  * data of the libxml2 library once processing has ended. | ||||
|  * | ||||
|  * WARNING: if your application is multithreaded or has plugin support | ||||
|  *          calling this may crash the application if another thread or | ||||
|  *          a plugin is still using libxml2. It's sometimes very hard to | ||||
|  *          guess if libxml2 is in use in the application, some libraries | ||||
|  *          or plugins may use it without notice. In case of doubt abstain | ||||
|  *          from calling this function or do it just before calling exit() | ||||
|  *          to avoid leak reports from valgrind ! | ||||
|  */ | ||||
| void | ||||
| xmlCleanupThreads(void) | ||||
| { | ||||
| #ifdef DEBUG_THREADS | ||||
|     xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * xmlCleanupThreadsInternal: | ||||
|  * | ||||
|  * Used to to cleanup all the thread related data. | ||||
|  */ | ||||
| void | ||||
| xmlCleanupThreadsInternal(void) | ||||
| { | ||||
| #ifdef HAVE_POSIX_THREADS | ||||
|     if (libxml_is_threaded != 0) | ||||
|     pthread_key_delete(globalkey); | ||||
|     once_control = once_control_init; | ||||
| #elif defined(HAVE_WIN32_THREADS) | ||||
| #if !defined(HAVE_COMPILER_TLS) | ||||
|     if (globalkey != TLS_OUT_OF_INDEXES) { | ||||
| @@ -807,52 +798,9 @@ xmlCleanupThreads(void) | ||||
|     DeleteCriticalSection(&cleanup_helpers_cs); | ||||
| #endif | ||||
| #endif | ||||
|     run_once.done = 0; | ||||
|     run_once.control = 0; | ||||
| #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 void | ||||
| xmlOnceInit(void) | ||||
| { | ||||
| #ifdef HAVE_POSIX_THREADS | ||||
|     (void) pthread_key_create(&globalkey, xmlFreeGlobalState); | ||||
|     mainthread = pthread_self(); | ||||
|     __xmlInitializeDict(); | ||||
| #elif defined(HAVE_WIN32_THREADS) | ||||
|     if (!run_once.done) { | ||||
|         if (InterlockedIncrement(&run_once.control) == 1) { | ||||
| #if !defined(HAVE_COMPILER_TLS) | ||||
| #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) | ||||
|             InitializeCriticalSection(&cleanup_helpers_cs); | ||||
| #endif | ||||
|             globalkey = TlsAlloc(); | ||||
| #endif | ||||
|             mainthread = GetCurrentThreadId(); | ||||
| 	    __xmlInitializeDict(); | ||||
|             run_once.done = 1; | ||||
|         } else { | ||||
|             /* Another thread is working; give up our slice and | ||||
|              * wait until they're done. */ | ||||
|             while (!run_once.done) | ||||
|                 Sleep(0); | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * DllMain: | ||||
|  * @hinstDLL: handle to DLL instance | ||||
|   | ||||
		Reference in New Issue
	
	Block a user