| 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 |
| 11 #include "libxml.h" | 11 #include "libxml.h" |
| 12 | 12 |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include <libxml/threads.h> | 15 #include <libxml/threads.h> |
| 16 #include <libxml/globals.h> | 16 #include <libxml/globals.h> |
| 17 | 17 |
| 18 #ifdef HAVE_SYS_TYPES_H | 18 #ifdef HAVE_SYS_TYPES_H |
| 19 #include <sys/types.h> | 19 #include <sys/types.h> |
| 20 #endif | 20 #endif |
| 21 #ifdef HAVE_UNISTD_H | 21 #ifdef HAVE_UNISTD_H |
| 22 #include <unistd.h> | 22 #include <unistd.h> |
| 23 #endif | 23 #endif |
| 24 #ifdef HAVE_STDLIB_H | 24 #ifdef HAVE_STDLIB_H |
| 25 #include <stdlib.h> | 25 #include <stdlib.h> |
| 26 #endif | 26 #endif |
| 27 #ifdef HAVE_PTHREAD_H | 27 #ifdef HAVE_PTHREAD_H |
| 28 #include <pthread.h> | 28 #include <pthread.h> |
| 29 #endif | 29 #elif defined HAVE_WIN32_THREADS |
| 30 | |
| 31 #ifdef HAVE_WIN32_THREADS | |
| 32 #include <windows.h> | 30 #include <windows.h> |
| 33 #ifndef HAVE_COMPILER_TLS | 31 #ifndef HAVE_COMPILER_TLS |
| 34 #include <process.h> | 32 #include <process.h> |
| 35 #endif | 33 #endif |
| 36 #endif | 34 #endif |
| 37 | 35 |
| 38 #ifdef HAVE_BEOS_THREADS | 36 #ifdef HAVE_BEOS_THREADS |
| 39 #include <OS.h> | 37 #include <OS.h> |
| 40 #include <TLS.h> | 38 #include <TLS.h> |
| 41 #endif | 39 #endif |
| (...skipping 14 matching lines...) Expand all Loading... |
| 56 void (*__init_routine) (void)) | 54 void (*__init_routine) (void)) |
| 57 __attribute((weak)); | 55 __attribute((weak)); |
| 58 extern void *pthread_getspecific (pthread_key_t __key) | 56 extern void *pthread_getspecific (pthread_key_t __key) |
| 59 __attribute((weak)); | 57 __attribute((weak)); |
| 60 extern int pthread_setspecific (pthread_key_t __key, | 58 extern int pthread_setspecific (pthread_key_t __key, |
| 61 __const void *__pointer) | 59 __const void *__pointer) |
| 62 __attribute((weak)); | 60 __attribute((weak)); |
| 63 extern int pthread_key_create (pthread_key_t *__key, | 61 extern int pthread_key_create (pthread_key_t *__key, |
| 64 void (*__destr_function) (void *)) | 62 void (*__destr_function) (void *)) |
| 65 __attribute((weak)); | 63 __attribute((weak)); |
| 64 extern int pthread_key_delete (pthread_key_t __key) |
| 65 __attribute((weak)); |
| 66 extern int pthread_mutex_init () | 66 extern int pthread_mutex_init () |
| 67 __attribute((weak)); | 67 __attribute((weak)); |
| 68 extern int pthread_mutex_destroy () | 68 extern int pthread_mutex_destroy () |
| 69 __attribute((weak)); | 69 __attribute((weak)); |
| 70 extern int pthread_mutex_lock () | 70 extern int pthread_mutex_lock () |
| 71 __attribute((weak)); | 71 __attribute((weak)); |
| 72 extern int pthread_mutex_unlock () | 72 extern int pthread_mutex_unlock () |
| 73 __attribute((weak)); | 73 __attribute((weak)); |
| 74 extern int pthread_cond_init () | 74 extern int pthread_cond_init () |
| 75 __attribute((weak)); | 75 __attribute((weak)); |
| 76 extern int pthread_cond_destroy () |
| 77 __attribute((weak)); |
| 78 extern int pthread_cond_wait () |
| 79 __attribute((weak)); |
| 76 extern int pthread_equal () | 80 extern int pthread_equal () |
| 77 __attribute((weak)); | 81 __attribute((weak)); |
| 78 extern pthread_t pthread_self () | 82 extern pthread_t pthread_self () |
| 79 __attribute((weak)); | 83 __attribute((weak)); |
| 80 extern int pthread_key_create () | 84 extern int pthread_key_create () |
| 81 __attribute((weak)); | 85 __attribute((weak)); |
| 86 extern int pthread_key_delete () |
| 87 __attribute((weak)); |
| 82 extern int pthread_cond_signal () | 88 extern int pthread_cond_signal () |
| 83 __attribute((weak)); | 89 __attribute((weak)); |
| 84 #endif | 90 #endif |
| 85 #endif /* linux */ | 91 #endif /* linux */ |
| 86 #endif /* __GNUC__ */ | 92 #endif /* __GNUC__ */ |
| 87 #endif /* HAVE_PTHREAD_H */ | 93 #endif /* HAVE_PTHREAD_H */ |
| 88 | 94 |
| 89 /* | 95 /* |
| 90 * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree | 96 * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree |
| 91 * to avoid some crazyness since xmlMalloc/xmlFree may actually | 97 * to avoid some crazyness since xmlMalloc/xmlFree may actually |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 return; | 403 return; |
| 398 #ifdef HAVE_PTHREAD_H | 404 #ifdef HAVE_PTHREAD_H |
| 399 if (libxml_is_threaded == 0) | 405 if (libxml_is_threaded == 0) |
| 400 return; | 406 return; |
| 401 | 407 |
| 402 pthread_mutex_lock(&tok->lock); | 408 pthread_mutex_lock(&tok->lock); |
| 403 tok->held--; | 409 tok->held--; |
| 404 if (tok->held == 0) { | 410 if (tok->held == 0) { |
| 405 if (tok->waiters) | 411 if (tok->waiters) |
| 406 pthread_cond_signal(&tok->cv); | 412 pthread_cond_signal(&tok->cv); |
| 407 tok->tid = 0; | 413 memset(&tok->tid, 0, sizeof(tok->tid)); |
| 408 } | 414 } |
| 409 pthread_mutex_unlock(&tok->lock); | 415 pthread_mutex_unlock(&tok->lock); |
| 410 #elif defined HAVE_WIN32_THREADS | 416 #elif defined HAVE_WIN32_THREADS |
| 411 if (!--tok->count) | 417 if (!--tok->count) |
| 412 LeaveCriticalSection(&tok->cs); | 418 LeaveCriticalSection(&tok->cs); |
| 413 #elif defined HAVE_BEOS_THREADS | 419 #elif defined HAVE_BEOS_THREADS |
| 414 if (tok->lock->tid == find_thread(NULL)) { | 420 if (tok->lock->tid == find_thread(NULL)) { |
| 415 tok->count--; | 421 tok->count--; |
| 416 if (tok->count == 0) { | 422 if (tok->count == 0) { |
| 417 xmlMutexUnlock(tok->lock); | 423 xmlMutexUnlock(tok->lock); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 520 |
| 515 /** | 521 /** |
| 516 * xmlGlobalInitMutexDestroy | 522 * xmlGlobalInitMutexDestroy |
| 517 * | 523 * |
| 518 * Makes sure that the global initialization mutex is destroyed before | 524 * Makes sure that the global initialization mutex is destroyed before |
| 519 * application termination. | 525 * application termination. |
| 520 */ | 526 */ |
| 521 void | 527 void |
| 522 __xmlGlobalInitMutexDestroy(void) | 528 __xmlGlobalInitMutexDestroy(void) |
| 523 { | 529 { |
| 524 #if defined HAVE_WIN32_THREADS | 530 #ifdef HAVE_PTHREAD_H |
| 531 #elif defined HAVE_WIN32_THREADS |
| 525 if (global_init_lock != NULL) { | 532 if (global_init_lock != NULL) { |
| 526 DeleteCriticalSection(global_init_lock); | 533 DeleteCriticalSection(global_init_lock); |
| 527 free(global_init_lock); | 534 free(global_init_lock); |
| 528 global_init_lock = NULL; | 535 global_init_lock = NULL; |
| 529 } | 536 } |
| 530 #endif | 537 #endif |
| 531 } | 538 } |
| 532 | 539 |
| 533 /************************************************************************ | 540 /************************************************************************ |
| 534 * * | 541 * * |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 "xmlGetGlobalState: out of memory\n"); | 585 "xmlGetGlobalState: out of memory\n"); |
| 579 return (NULL); | 586 return (NULL); |
| 580 } | 587 } |
| 581 | 588 |
| 582 memset(gs, 0, sizeof(xmlGlobalState)); | 589 memset(gs, 0, sizeof(xmlGlobalState)); |
| 583 xmlInitializeGlobalState(gs); | 590 xmlInitializeGlobalState(gs); |
| 584 return (gs); | 591 return (gs); |
| 585 } | 592 } |
| 586 #endif /* LIBXML_THREAD_ENABLED */ | 593 #endif /* LIBXML_THREAD_ENABLED */ |
| 587 | 594 |
| 588 | 595 #ifdef HAVE_PTHREAD_H |
| 589 #ifdef HAVE_WIN32_THREADS | 596 #elif defined HAVE_WIN32_THREADS |
| 590 #if !defined(HAVE_COMPILER_TLS) | 597 #if !defined(HAVE_COMPILER_TLS) |
| 591 #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) | 598 #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) |
| 592 typedef struct _xmlGlobalStateCleanupHelperParams { | 599 typedef struct _xmlGlobalStateCleanupHelperParams { |
| 593 HANDLE thread; | 600 HANDLE thread; |
| 594 void *memory; | 601 void *memory; |
| 595 } xmlGlobalStateCleanupHelperParams; | 602 } xmlGlobalStateCleanupHelperParams; |
| 596 | 603 |
| 597 static void XMLCDECL | 604 static void XMLCDECL |
| 598 xmlGlobalStateCleanupHelper(void *p) | 605 xmlGlobalStateCleanupHelper(void *p) |
| 599 { | 606 { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 if (globalval == NULL) { | 694 if (globalval == NULL) { |
| 688 xmlGlobalState *tsd = xmlNewGlobalState(); | 695 xmlGlobalState *tsd = xmlNewGlobalState(); |
| 689 | 696 |
| 690 if (tsd == NULL) | 697 if (tsd == NULL) |
| 691 return(NULL); | 698 return(NULL); |
| 692 p = (xmlGlobalStateCleanupHelperParams *) | 699 p = (xmlGlobalStateCleanupHelperParams *) |
| 693 malloc(sizeof(xmlGlobalStateCleanupHelperParams)); | 700 malloc(sizeof(xmlGlobalStateCleanupHelperParams)); |
| 694 if (p == NULL) { | 701 if (p == NULL) { |
| 695 xmlGenericError(xmlGenericErrorContext, | 702 xmlGenericError(xmlGenericErrorContext, |
| 696 "xmlGetGlobalState: out of memory\n"); | 703 "xmlGetGlobalState: out of memory\n"); |
| 704 xmlFreeGlobalState(tsd); |
| 697 return(NULL); | 705 return(NULL); |
| 698 } | 706 } |
| 699 p->memory = tsd; | 707 p->memory = tsd; |
| 700 #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) | 708 #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) |
| 701 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), | 709 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), |
| 702 GetCurrentProcess(), &p->thread, 0, TRUE, | 710 GetCurrentProcess(), &p->thread, 0, TRUE, |
| 703 DUPLICATE_SAME_ACCESS); | 711 DUPLICATE_SAME_ACCESS); |
| 704 TlsSetValue(globalkey, tsd); | 712 TlsSetValue(globalkey, tsd); |
| 705 _beginthread(xmlGlobalStateCleanupHelper, 0, p); | 713 _beginthread(xmlGlobalStateCleanupHelper, 0, p); |
| 706 #else | 714 #else |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 /************************************************************************ | 750 /************************************************************************ |
| 743 * * | 751 * * |
| 744 * Library wide thread interfaces * | 752 * Library wide thread interfaces * |
| 745 * * | 753 * * |
| 746 ************************************************************************/ | 754 ************************************************************************/ |
| 747 | 755 |
| 748 /** | 756 /** |
| 749 * xmlGetThreadId: | 757 * xmlGetThreadId: |
| 750 * | 758 * |
| 751 * xmlGetThreadId() find the current thread ID number | 759 * xmlGetThreadId() find the current thread ID number |
| 760 * Note that this is likely to be broken on some platforms using pthreads |
| 761 * as the specification doesn't mandate pthread_t to be an integer type |
| 752 * | 762 * |
| 753 * Returns the current thread ID number | 763 * Returns the current thread ID number |
| 754 */ | 764 */ |
| 755 int | 765 int |
| 756 xmlGetThreadId(void) | 766 xmlGetThreadId(void) |
| 757 { | 767 { |
| 758 #ifdef HAVE_PTHREAD_H | 768 #ifdef HAVE_PTHREAD_H |
| 769 pthread_t id; |
| 770 int ret; |
| 771 |
| 759 if (libxml_is_threaded == 0) | 772 if (libxml_is_threaded == 0) |
| 760 return (0); | 773 return (0); |
| 761 return ((int) pthread_self()); | 774 id = pthread_self(); |
| 775 /* horrible but preserves compat, see warning above */ |
| 776 memcpy(&ret, &id, sizeof(ret)); |
| 777 return (ret); |
| 762 #elif defined HAVE_WIN32_THREADS | 778 #elif defined HAVE_WIN32_THREADS |
| 763 return GetCurrentThreadId(); | 779 return GetCurrentThreadId(); |
| 764 #elif defined HAVE_BEOS_THREADS | 780 #elif defined HAVE_BEOS_THREADS |
| 765 return find_thread(NULL); | 781 return find_thread(NULL); |
| 766 #else | 782 #else |
| 767 return ((int) 0); | 783 return ((int) 0); |
| 768 #endif | 784 #endif |
| 769 } | 785 } |
| 770 | 786 |
| 771 /** | 787 /** |
| (...skipping 15 matching lines...) Expand all Loading... |
| 787 #elif defined HAVE_WIN32_THREADS | 803 #elif defined HAVE_WIN32_THREADS |
| 788 xmlOnceInit(); | 804 xmlOnceInit(); |
| 789 #elif defined HAVE_BEOS_THREADS | 805 #elif defined HAVE_BEOS_THREADS |
| 790 xmlOnceInit(); | 806 xmlOnceInit(); |
| 791 #endif | 807 #endif |
| 792 | 808 |
| 793 #ifdef DEBUG_THREADS | 809 #ifdef DEBUG_THREADS |
| 794 xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n"); | 810 xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n"); |
| 795 #endif | 811 #endif |
| 796 #ifdef HAVE_PTHREAD_H | 812 #ifdef HAVE_PTHREAD_H |
| 797 return (mainthread == pthread_self()); | 813 return (pthread_equal(mainthread,pthread_self())); |
| 798 #elif defined HAVE_WIN32_THREADS | 814 #elif defined HAVE_WIN32_THREADS |
| 799 return (mainthread == GetCurrentThreadId()); | 815 return (mainthread == GetCurrentThreadId()); |
| 800 #elif defined HAVE_BEOS_THREADS | 816 #elif defined HAVE_BEOS_THREADS |
| 801 return (mainthread == find_thread(NULL)); | 817 return (mainthread == find_thread(NULL)); |
| 802 #else | 818 #else |
| 803 return (1); | 819 return (1); |
| 804 #endif | 820 #endif |
| 805 } | 821 } |
| 806 | 822 |
| 807 /** | 823 /** |
| (...skipping 28 matching lines...) Expand all Loading... |
| 836 | 852 |
| 837 /** | 853 /** |
| 838 * xmlInitThreads: | 854 * xmlInitThreads: |
| 839 * | 855 * |
| 840 * xmlInitThreads() is used to to initialize all the thread related | 856 * xmlInitThreads() is used to to initialize all the thread related |
| 841 * data of the libxml2 library. | 857 * data of the libxml2 library. |
| 842 */ | 858 */ |
| 843 void | 859 void |
| 844 xmlInitThreads(void) | 860 xmlInitThreads(void) |
| 845 { | 861 { |
| 846 #ifdef DEBUG_THREADS | |
| 847 xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n"); | |
| 848 #endif | |
| 849 #if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBX
ML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) | |
| 850 InitializeCriticalSection(&cleanup_helpers_cs); | |
| 851 #endif | |
| 852 #ifdef HAVE_PTHREAD_H | 862 #ifdef HAVE_PTHREAD_H |
| 853 if (libxml_is_threaded == -1) { | 863 if (libxml_is_threaded == -1) { |
| 854 if ((pthread_once != NULL) && | 864 if ((pthread_once != NULL) && |
| 855 (pthread_getspecific != NULL) && | 865 (pthread_getspecific != NULL) && |
| 856 (pthread_setspecific != NULL) && | 866 (pthread_setspecific != NULL) && |
| 857 (pthread_key_create != NULL) && | 867 (pthread_key_create != NULL) && |
| 868 (pthread_key_delete != NULL) && |
| 858 (pthread_mutex_init != NULL) && | 869 (pthread_mutex_init != NULL) && |
| 859 (pthread_mutex_destroy != NULL) && | 870 (pthread_mutex_destroy != NULL) && |
| 860 (pthread_mutex_lock != NULL) && | 871 (pthread_mutex_lock != NULL) && |
| 861 (pthread_mutex_unlock != NULL) && | 872 (pthread_mutex_unlock != NULL) && |
| 862 (pthread_cond_init != NULL) && | 873 (pthread_cond_init != NULL) && |
| 874 (pthread_cond_destroy != NULL) && |
| 875 (pthread_cond_wait != NULL) && |
| 863 (pthread_equal != NULL) && | 876 (pthread_equal != NULL) && |
| 864 (pthread_self != NULL) && | 877 (pthread_self != NULL) && |
| 865 (pthread_cond_signal != NULL)) { | 878 (pthread_cond_signal != NULL)) { |
| 866 libxml_is_threaded = 1; | 879 libxml_is_threaded = 1; |
| 867 | 880 |
| 868 /* fprintf(stderr, "Running multithreaded\n"); */ | 881 /* fprintf(stderr, "Running multithreaded\n"); */ |
| 869 } else { | 882 } else { |
| 870 | 883 |
| 871 /* fprintf(stderr, "Running without multithread\n"); */ | 884 /* fprintf(stderr, "Running without multithread\n"); */ |
| 872 libxml_is_threaded = 0; | 885 libxml_is_threaded = 0; |
| 873 } | 886 } |
| 874 } | 887 } |
| 888 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LI
BXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) |
| 889 InitializeCriticalSection(&cleanup_helpers_cs); |
| 875 #endif | 890 #endif |
| 876 } | 891 } |
| 877 | 892 |
| 878 /** | 893 /** |
| 879 * xmlCleanupThreads: | 894 * xmlCleanupThreads: |
| 880 * | 895 * |
| 881 * xmlCleanupThreads() is used to to cleanup all the thread related | 896 * xmlCleanupThreads() is used to to cleanup all the thread related |
| 882 * data of the libxml2 library once processing has ended. | 897 * data of the libxml2 library once processing has ended. |
| 898 * |
| 899 * WARNING: if your application is multithreaded or has plugin support |
| 900 * calling this may crash the application if another thread or |
| 901 * a plugin is still using libxml2. It's sometimes very hard to |
| 902 * guess if libxml2 is in use in the application, some libraries |
| 903 * or plugins may use it without notice. In case of doubt abstain |
| 904 * from calling this function or do it just before calling exit() |
| 905 * to avoid leak reports from valgrind ! |
| 883 */ | 906 */ |
| 884 void | 907 void |
| 885 xmlCleanupThreads(void) | 908 xmlCleanupThreads(void) |
| 886 { | 909 { |
| 887 #ifdef DEBUG_THREADS | 910 #ifdef DEBUG_THREADS |
| 888 xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); | 911 xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); |
| 889 #endif | 912 #endif |
| 890 #if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBX
ML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) | 913 #ifdef HAVE_PTHREAD_H |
| 914 if ((libxml_is_threaded) && (pthread_key_delete != NULL)) |
| 915 pthread_key_delete(globalkey); |
| 916 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LI
BXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) |
| 891 if (globalkey != TLS_OUT_OF_INDEXES) { | 917 if (globalkey != TLS_OUT_OF_INDEXES) { |
| 892 xmlGlobalStateCleanupHelperParams *p; | 918 xmlGlobalStateCleanupHelperParams *p; |
| 893 | 919 |
| 894 EnterCriticalSection(&cleanup_helpers_cs); | 920 EnterCriticalSection(&cleanup_helpers_cs); |
| 895 p = cleanup_helpers_head; | 921 p = cleanup_helpers_head; |
| 896 while (p != NULL) { | 922 while (p != NULL) { |
| 897 xmlGlobalStateCleanupHelperParams *temp = p; | 923 xmlGlobalStateCleanupHelperParams *temp = p; |
| 898 | 924 |
| 899 p = p->next; | 925 p = p->next; |
| 900 xmlFreeGlobalState(temp->memory); | 926 xmlFreeGlobalState(temp->memory); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 919 * pthread_once() in association with the once_control variable to ensure | 945 * pthread_once() in association with the once_control variable to ensure |
| 920 * that the function is only called once. See man pthread_once for more | 946 * that the function is only called once. See man pthread_once for more |
| 921 * details. | 947 * details. |
| 922 */ | 948 */ |
| 923 static void | 949 static void |
| 924 xmlOnceInit(void) | 950 xmlOnceInit(void) |
| 925 { | 951 { |
| 926 #ifdef HAVE_PTHREAD_H | 952 #ifdef HAVE_PTHREAD_H |
| 927 (void) pthread_key_create(&globalkey, xmlFreeGlobalState); | 953 (void) pthread_key_create(&globalkey, xmlFreeGlobalState); |
| 928 mainthread = pthread_self(); | 954 mainthread = pthread_self(); |
| 929 #endif | 955 #elif defined(HAVE_WIN32_THREADS) |
| 930 | |
| 931 #if defined(HAVE_WIN32_THREADS) | |
| 932 if (!run_once.done) { | 956 if (!run_once.done) { |
| 933 if (InterlockedIncrement(&run_once.control) == 1) { | 957 if (InterlockedIncrement(&run_once.control) == 1) { |
| 934 #if !defined(HAVE_COMPILER_TLS) | 958 #if !defined(HAVE_COMPILER_TLS) |
| 935 globalkey = TlsAlloc(); | 959 globalkey = TlsAlloc(); |
| 936 #endif | 960 #endif |
| 937 mainthread = GetCurrentThreadId(); | 961 mainthread = GetCurrentThreadId(); |
| 938 run_once.done = 1; | 962 run_once.done = 1; |
| 939 } else { | 963 } else { |
| 940 /* Another thread is working; give up our slice and | 964 /* Another thread is working; give up our slice and |
| 941 * wait until they're done. */ | 965 * wait until they're done. */ |
| 942 while (!run_once.done) | 966 while (!run_once.done) |
| 943 Sleep(0); | 967 Sleep(0); |
| 944 } | 968 } |
| 945 } | 969 } |
| 946 #endif | 970 #elif defined HAVE_BEOS_THREADS |
| 947 | |
| 948 #ifdef HAVE_BEOS_THREADS | |
| 949 if (atomic_add(&run_once_init, 1) == 0) { | 971 if (atomic_add(&run_once_init, 1) == 0) { |
| 950 globalkey = tls_allocate(); | 972 globalkey = tls_allocate(); |
| 951 tls_set(globalkey, NULL); | 973 tls_set(globalkey, NULL); |
| 952 mainthread = find_thread(NULL); | 974 mainthread = find_thread(NULL); |
| 953 } else | 975 } else |
| 954 atomic_add(&run_once_init, -1); | 976 atomic_add(&run_once_init, -1); |
| 955 #endif | 977 #endif |
| 956 } | 978 } |
| 957 #endif | 979 #endif |
| 958 | 980 |
| 959 /** | 981 /** |
| 960 * DllMain: | 982 * DllMain: |
| 961 * @hinstDLL: handle to DLL instance | 983 * @hinstDLL: handle to DLL instance |
| 962 * @fdwReason: Reason code for entry | 984 * @fdwReason: Reason code for entry |
| 963 * @lpvReserved: generic pointer (depends upon reason code) | 985 * @lpvReserved: generic pointer (depends upon reason code) |
| 964 * | 986 * |
| 965 * Entry point for Windows library. It is being used to free thread-specific | 987 * Entry point for Windows library. It is being used to free thread-specific |
| 966 * storage. | 988 * storage. |
| 967 * | 989 * |
| 968 * Returns TRUE always | 990 * Returns TRUE always |
| 969 */ | 991 */ |
| 970 #if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBX
ML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) | 992 #ifdef HAVE_PTHREAD_H |
| 993 #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LI
BXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) |
| 971 #if defined(LIBXML_STATIC_FOR_DLL) | 994 #if defined(LIBXML_STATIC_FOR_DLL) |
| 972 BOOL XMLCALL | 995 BOOL XMLCALL |
| 973 xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | 996 xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
| 974 #else | 997 #else |
| 975 BOOL WINAPI | 998 BOOL WINAPI |
| 976 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | 999 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) |
| 977 #endif | 1000 #endif |
| 978 { | 1001 { |
| 979 switch (fdwReason) { | 1002 switch (fdwReason) { |
| 980 case DLL_THREAD_DETACH: | 1003 case DLL_THREAD_DETACH: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1000 free(p); | 1023 free(p); |
| 1001 } | 1024 } |
| 1002 } | 1025 } |
| 1003 break; | 1026 break; |
| 1004 } | 1027 } |
| 1005 return TRUE; | 1028 return TRUE; |
| 1006 } | 1029 } |
| 1007 #endif | 1030 #endif |
| 1008 #define bottom_threads | 1031 #define bottom_threads |
| 1009 #include "elfgcchack.h" | 1032 #include "elfgcchack.h" |
| OLD | NEW |