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 |