| OLD | NEW |
| 1 /** | 1 /** |
| 2 * threads.c: set of generic threading related routines | 2 * threads.c: set of generic threading related routines |
| 3 * | 3 * |
| 4 * See Copyright for the status of this software. | 4 * See Copyright for the status of this software. |
| 5 * | 5 * |
| 6 * Gary Pennington <Gary.Pennington@uk.sun.com> | 6 * Gary Pennington <Gary.Pennington@uk.sun.com> |
| 7 * daniel@veillard.com | 7 * daniel@veillard.com |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 #define IN_LIBXML | 10 #define IN_LIBXML |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 /* | 139 /* |
| 140 * This module still has some internal static data. | 140 * This module still has some internal static data. |
| 141 * - xmlLibraryLock a global lock | 141 * - xmlLibraryLock a global lock |
| 142 * - globalkey used for per-thread data | 142 * - globalkey used for per-thread data |
| 143 */ | 143 */ |
| 144 | 144 |
| 145 #ifdef HAVE_PTHREAD_H | 145 #ifdef HAVE_PTHREAD_H |
| 146 static pthread_key_t globalkey; | 146 static pthread_key_t globalkey; |
| 147 static pthread_t mainthread; | 147 static pthread_t mainthread; |
| 148 static pthread_once_t once_control = PTHREAD_ONCE_INIT; | 148 static pthread_once_t once_control = PTHREAD_ONCE_INIT; |
| 149 static pthread_once_t once_control_init = PTHREAD_ONCE_INIT; |
| 149 static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER; | 150 static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER; |
| 150 #elif defined HAVE_WIN32_THREADS | 151 #elif defined HAVE_WIN32_THREADS |
| 151 #if defined(HAVE_COMPILER_TLS) | 152 #if defined(HAVE_COMPILER_TLS) |
| 152 static __declspec(thread) xmlGlobalState tlstate; | 153 static __declspec(thread) xmlGlobalState tlstate; |
| 153 static __declspec(thread) int tlstate_inited = 0; | 154 static __declspec(thread) int tlstate_inited = 0; |
| 154 #else /* HAVE_COMPILER_TLS */ | 155 #else /* HAVE_COMPILER_TLS */ |
| 155 static DWORD globalkey = TLS_OUT_OF_INDEXES; | 156 static DWORD globalkey = TLS_OUT_OF_INDEXES; |
| 156 #endif /* HAVE_COMPILER_TLS */ | 157 #endif /* HAVE_COMPILER_TLS */ |
| 157 static DWORD mainthread; | 158 static DWORD mainthread; |
| 158 static struct { | 159 static struct { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 #ifdef HAVE_PTHREAD_H | 245 #ifdef HAVE_PTHREAD_H |
| 245 if (libxml_is_threaded != 0) | 246 if (libxml_is_threaded != 0) |
| 246 pthread_mutex_lock(&tok->lock); | 247 pthread_mutex_lock(&tok->lock); |
| 247 #elif defined HAVE_WIN32_THREADS | 248 #elif defined HAVE_WIN32_THREADS |
| 248 WaitForSingleObject(tok->mutex, INFINITE); | 249 WaitForSingleObject(tok->mutex, INFINITE); |
| 249 #elif defined HAVE_BEOS_THREADS | 250 #elif defined HAVE_BEOS_THREADS |
| 250 if (acquire_sem(tok->sem) != B_NO_ERROR) { | 251 if (acquire_sem(tok->sem) != B_NO_ERROR) { |
| 251 #ifdef DEBUG_THREADS | 252 #ifdef DEBUG_THREADS |
| 252 xmlGenericError(xmlGenericErrorContext, | 253 xmlGenericError(xmlGenericErrorContext, |
| 253 "xmlMutexLock():BeOS:Couldn't aquire semaphore\n"); | 254 "xmlMutexLock():BeOS:Couldn't aquire semaphore\n"); |
| 254 exit(); | |
| 255 #endif | 255 #endif |
| 256 } | 256 } |
| 257 tok->tid = find_thread(NULL); | 257 tok->tid = find_thread(NULL); |
| 258 #endif | 258 #endif |
| 259 | 259 |
| 260 } | 260 } |
| 261 | 261 |
| 262 /** | 262 /** |
| 263 * xmlMutexUnlock: | 263 * xmlMutexUnlock: |
| 264 * @tok: the simple mutex | 264 * @tok: the simple mutex |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 while (tok->held) | 371 while (tok->held) |
| 372 pthread_cond_wait(&tok->cv, &tok->lock); | 372 pthread_cond_wait(&tok->cv, &tok->lock); |
| 373 tok->waiters--; | 373 tok->waiters--; |
| 374 } | 374 } |
| 375 } | 375 } |
| 376 tok->tid = pthread_self(); | 376 tok->tid = pthread_self(); |
| 377 tok->held = 1; | 377 tok->held = 1; |
| 378 pthread_mutex_unlock(&tok->lock); | 378 pthread_mutex_unlock(&tok->lock); |
| 379 #elif defined HAVE_WIN32_THREADS | 379 #elif defined HAVE_WIN32_THREADS |
| 380 EnterCriticalSection(&tok->cs); | 380 EnterCriticalSection(&tok->cs); |
| 381 ++tok->count; | 381 tok->count++; |
| 382 #elif defined HAVE_BEOS_THREADS | 382 #elif defined HAVE_BEOS_THREADS |
| 383 if (tok->lock->tid == find_thread(NULL)) { | 383 if (tok->lock->tid == find_thread(NULL)) { |
| 384 tok->count++; | 384 tok->count++; |
| 385 return; | 385 return; |
| 386 } else { | 386 } else { |
| 387 xmlMutexLock(tok->lock); | 387 xmlMutexLock(tok->lock); |
| 388 tok->count = 1; | 388 tok->count = 1; |
| 389 } | 389 } |
| 390 #endif | 390 #endif |
| 391 } | 391 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 407 | 407 |
| 408 pthread_mutex_lock(&tok->lock); | 408 pthread_mutex_lock(&tok->lock); |
| 409 tok->held--; | 409 tok->held--; |
| 410 if (tok->held == 0) { | 410 if (tok->held == 0) { |
| 411 if (tok->waiters) | 411 if (tok->waiters) |
| 412 pthread_cond_signal(&tok->cv); | 412 pthread_cond_signal(&tok->cv); |
| 413 memset(&tok->tid, 0, sizeof(tok->tid)); | 413 memset(&tok->tid, 0, sizeof(tok->tid)); |
| 414 } | 414 } |
| 415 pthread_mutex_unlock(&tok->lock); | 415 pthread_mutex_unlock(&tok->lock); |
| 416 #elif defined HAVE_WIN32_THREADS | 416 #elif defined HAVE_WIN32_THREADS |
| 417 if (!--tok->count) | 417 if (tok->count > 0) { |
| 418 LeaveCriticalSection(&tok->cs); | 418 LeaveCriticalSection(&tok->cs); |
| 419 tok->count--; |
| 420 } |
| 419 #elif defined HAVE_BEOS_THREADS | 421 #elif defined HAVE_BEOS_THREADS |
| 420 if (tok->lock->tid == find_thread(NULL)) { | 422 if (tok->lock->tid == find_thread(NULL)) { |
| 421 tok->count--; | 423 tok->count--; |
| 422 if (tok->count == 0) { | 424 if (tok->count == 0) { |
| 423 xmlMutexUnlock(tok->lock); | 425 xmlMutexUnlock(tok->lock); |
| 424 } | 426 } |
| 425 return; | 427 return; |
| 426 } | 428 } |
| 427 #endif | 429 #endif |
| 428 } | 430 } |
| 429 | 431 |
| 430 /** | 432 /** |
| 431 * xmlGlobalInitMutexLock | 433 * xmlGlobalInitMutexLock |
| 432 * | 434 * |
| 433 * Makes sure that the global initialization mutex is initialized and | 435 * Makes sure that the global initialization mutex is initialized and |
| 434 * locks it. | 436 * locks it. |
| 435 */ | 437 */ |
| 436 void | 438 void |
| 437 __xmlGlobalInitMutexLock(void) | 439 __xmlGlobalInitMutexLock(void) |
| 438 { | 440 { |
| 439 /* Make sure the global init lock is initialized and then lock it. */ | 441 /* Make sure the global init lock is initialized and then lock it. */ |
| 440 #ifdef HAVE_PTHREAD_H | 442 #ifdef HAVE_PTHREAD_H |
| 441 /* The mutex is statically initialized, so we just lock it. */ | 443 /* The mutex is statically initialized, so we just lock it. */ |
| 442 pthread_mutex_lock(&global_init_lock); | 444 if (pthread_mutex_lock != NULL) |
| 445 pthread_mutex_lock(&global_init_lock); |
| 443 #elif defined HAVE_WIN32_THREADS | 446 #elif defined HAVE_WIN32_THREADS |
| 444 LPCRITICAL_SECTION cs; | 447 LPCRITICAL_SECTION cs; |
| 445 | 448 |
| 446 /* Create a new critical section */ | 449 /* Create a new critical section */ |
| 447 if (global_init_lock == NULL) { | 450 if (global_init_lock == NULL) { |
| 448 cs = malloc(sizeof(CRITICAL_SECTION)); | 451 cs = malloc(sizeof(CRITICAL_SECTION)); |
| 449 if (cs == NULL) { | 452 if (cs == NULL) { |
| 450 xmlGenericError(xmlGenericErrorContext, | 453 xmlGenericError(xmlGenericErrorContext, |
| 451 "xmlGlobalInitMutexLock: out of memory\n"); | 454 "xmlGlobalInitMutexLock: out of memory\n"); |
| 452 return; | 455 return; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 * section in the global_init_lock then discard the one | 494 * section in the global_init_lock then discard the one |
| 492 * allocated by this thread. */ | 495 * allocated by this thread. */ |
| 493 if (global_init_lock != sem) | 496 if (global_init_lock != sem) |
| 494 delete_sem(sem); | 497 delete_sem(sem); |
| 495 | 498 |
| 496 /* Acquire the chosen semaphore */ | 499 /* Acquire the chosen semaphore */ |
| 497 if (acquire_sem(global_init_lock) != B_NO_ERROR) { | 500 if (acquire_sem(global_init_lock) != B_NO_ERROR) { |
| 498 #ifdef DEBUG_THREADS | 501 #ifdef DEBUG_THREADS |
| 499 xmlGenericError(xmlGenericErrorContext, | 502 xmlGenericError(xmlGenericErrorContext, |
| 500 "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphor
e\n"); | 503 "xmlGlobalInitMutexLock():BeOS:Couldn't acquire semaphor
e\n"); |
| 501 exit(); | |
| 502 #endif | 504 #endif |
| 503 } | 505 } |
| 504 #endif | 506 #endif |
| 505 } | 507 } |
| 506 | 508 |
| 507 void | 509 void |
| 508 __xmlGlobalInitMutexUnlock(void) | 510 __xmlGlobalInitMutexUnlock(void) |
| 509 { | 511 { |
| 510 #ifdef HAVE_PTHREAD_H | 512 #ifdef HAVE_PTHREAD_H |
| 511 pthread_mutex_unlock(&global_init_lock); | 513 if (pthread_mutex_unlock != NULL) |
| 514 pthread_mutex_unlock(&global_init_lock); |
| 512 #elif defined HAVE_WIN32_THREADS | 515 #elif defined HAVE_WIN32_THREADS |
| 513 if (global_init_lock != NULL) { | 516 if (global_init_lock != NULL) { |
| 514 LeaveCriticalSection(global_init_lock); | 517 LeaveCriticalSection(global_init_lock); |
| 515 } | 518 } |
| 516 #elif defined HAVE_BEOS_THREADS | 519 #elif defined HAVE_BEOS_THREADS |
| 517 release_sem(global_init_lock); | 520 release_sem(global_init_lock); |
| 518 #endif | 521 #endif |
| 519 } | 522 } |
| 520 | 523 |
| 521 /** | 524 /** |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 */ | 909 */ |
| 907 void | 910 void |
| 908 xmlCleanupThreads(void) | 911 xmlCleanupThreads(void) |
| 909 { | 912 { |
| 910 #ifdef DEBUG_THREADS | 913 #ifdef DEBUG_THREADS |
| 911 xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); | 914 xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); |
| 912 #endif | 915 #endif |
| 913 #ifdef HAVE_PTHREAD_H | 916 #ifdef HAVE_PTHREAD_H |
| 914 if ((libxml_is_threaded) && (pthread_key_delete != NULL)) | 917 if ((libxml_is_threaded) && (pthread_key_delete != NULL)) |
| 915 pthread_key_delete(globalkey); | 918 pthread_key_delete(globalkey); |
| 919 once_control = once_control_init; |
| 916 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LI
BXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) | 920 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LI
BXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) |
| 917 if (globalkey != TLS_OUT_OF_INDEXES) { | 921 if (globalkey != TLS_OUT_OF_INDEXES) { |
| 918 xmlGlobalStateCleanupHelperParams *p; | 922 xmlGlobalStateCleanupHelperParams *p; |
| 919 | 923 |
| 920 EnterCriticalSection(&cleanup_helpers_cs); | 924 EnterCriticalSection(&cleanup_helpers_cs); |
| 921 p = cleanup_helpers_head; | 925 p = cleanup_helpers_head; |
| 922 while (p != NULL) { | 926 while (p != NULL) { |
| 923 xmlGlobalStateCleanupHelperParams *temp = p; | 927 xmlGlobalStateCleanupHelperParams *temp = p; |
| 924 | 928 |
| 925 p = p->next; | 929 p = p->next; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 945 * pthread_once() in association with the once_control variable to ensure | 949 * pthread_once() in association with the once_control variable to ensure |
| 946 * that the function is only called once. See man pthread_once for more | 950 * that the function is only called once. See man pthread_once for more |
| 947 * details. | 951 * details. |
| 948 */ | 952 */ |
| 949 static void | 953 static void |
| 950 xmlOnceInit(void) | 954 xmlOnceInit(void) |
| 951 { | 955 { |
| 952 #ifdef HAVE_PTHREAD_H | 956 #ifdef HAVE_PTHREAD_H |
| 953 (void) pthread_key_create(&globalkey, xmlFreeGlobalState); | 957 (void) pthread_key_create(&globalkey, xmlFreeGlobalState); |
| 954 mainthread = pthread_self(); | 958 mainthread = pthread_self(); |
| 959 __xmlInitializeDict(); |
| 955 #elif defined(HAVE_WIN32_THREADS) | 960 #elif defined(HAVE_WIN32_THREADS) |
| 956 if (!run_once.done) { | 961 if (!run_once.done) { |
| 957 if (InterlockedIncrement(&run_once.control) == 1) { | 962 if (InterlockedIncrement(&run_once.control) == 1) { |
| 958 #if !defined(HAVE_COMPILER_TLS) | 963 #if !defined(HAVE_COMPILER_TLS) |
| 959 globalkey = TlsAlloc(); | 964 globalkey = TlsAlloc(); |
| 960 #endif | 965 #endif |
| 961 mainthread = GetCurrentThreadId(); | 966 mainthread = GetCurrentThreadId(); |
| 967 __xmlInitializeDict(); |
| 962 run_once.done = 1; | 968 run_once.done = 1; |
| 963 } else { | 969 } else { |
| 964 /* Another thread is working; give up our slice and | 970 /* Another thread is working; give up our slice and |
| 965 * wait until they're done. */ | 971 * wait until they're done. */ |
| 966 while (!run_once.done) | 972 while (!run_once.done) |
| 967 Sleep(0); | 973 Sleep(0); |
| 968 } | 974 } |
| 969 } | 975 } |
| 970 #elif defined HAVE_BEOS_THREADS | 976 #elif defined HAVE_BEOS_THREADS |
| 971 if (atomic_add(&run_once_init, 1) == 0) { | 977 if (atomic_add(&run_once_init, 1) == 0) { |
| 972 globalkey = tls_allocate(); | 978 globalkey = tls_allocate(); |
| 973 tls_set(globalkey, NULL); | 979 tls_set(globalkey, NULL); |
| 974 mainthread = find_thread(NULL); | 980 mainthread = find_thread(NULL); |
| 981 __xmlInitializeDict(); |
| 975 } else | 982 } else |
| 976 atomic_add(&run_once_init, -1); | 983 atomic_add(&run_once_init, -1); |
| 977 #endif | 984 #endif |
| 978 } | 985 } |
| 979 #endif | 986 #endif |
| 980 | 987 |
| 981 /** | 988 /** |
| 982 * DllMain: | 989 * DllMain: |
| 983 * @hinstDLL: handle to DLL instance | 990 * @hinstDLL: handle to DLL instance |
| 984 * @fdwReason: Reason code for entry | 991 * @fdwReason: Reason code for entry |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 free(p); | 1030 free(p); |
| 1024 } | 1031 } |
| 1025 } | 1032 } |
| 1026 break; | 1033 break; |
| 1027 } | 1034 } |
| 1028 return TRUE; | 1035 return TRUE; |
| 1029 } | 1036 } |
| 1030 #endif | 1037 #endif |
| 1031 #define bottom_threads | 1038 #define bottom_threads |
| 1032 #include "elfgcchack.h" | 1039 #include "elfgcchack.h" |
| OLD | NEW |