| OLD | NEW |
| 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 /* This Source Code Form is subject to the terms of the Mozilla Public | 2 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 3 * License, v. 2.0. If a copy of the MPL was not distributed with this | 3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 5 | 5 |
| 6 /* | 6 /* |
| 7 ** File: ptthread.c | 7 ** File: ptthread.c |
| 8 ** Descritpion: Implemenation for threds using pthreds | 8 ** Descritpion: Implemenation for threds using pthreds |
| 9 ** Exports: ptthread.h | 9 ** Exports: ptthread.h |
| 10 */ | 10 */ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 static PRIntn pt_schedpriv = 0; | 45 static PRIntn pt_schedpriv = 0; |
| 46 extern PRLock *_pr_sleeplock; | 46 extern PRLock *_pr_sleeplock; |
| 47 | 47 |
| 48 static struct _PT_Bookeeping | 48 static struct _PT_Bookeeping |
| 49 { | 49 { |
| 50 PRLock *ml; /* a lock to protect ourselves */ | 50 PRLock *ml; /* a lock to protect ourselves */ |
| 51 PRCondVar *cv; /* used to signal global things */ | 51 PRCondVar *cv; /* used to signal global things */ |
| 52 PRInt32 system, user; /* a count of the two different types */ | 52 PRInt32 system, user; /* a count of the two different types */ |
| 53 PRUintn this_many; /* number of threads allowed for exit */ | 53 PRUintn this_many; /* number of threads allowed for exit */ |
| 54 pthread_key_t key; /* thread private data key */ | 54 pthread_key_t key; /* thread private data key */ |
| 55 PRBool keyCreated; /* whether 'key' should be deleted */ |
| 55 PRThread *first, *last; /* list of threads we know about */ | 56 PRThread *first, *last; /* list of threads we know about */ |
| 56 #if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) | 57 #if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) |
| 57 PRInt32 minPrio, maxPrio; /* range of scheduling priorities */ | 58 PRInt32 minPrio, maxPrio; /* range of scheduling priorities */ |
| 58 #endif | 59 #endif |
| 59 } pt_book = {0}; | 60 } pt_book = {0}; |
| 60 | 61 |
| 61 static void _pt_thread_death(void *arg); | 62 static void _pt_thread_death(void *arg); |
| 62 static void _pt_thread_death_internal(void *arg, PRBool callDestructors); | 63 static void _pt_thread_death_internal(void *arg, PRBool callDestructors); |
| 63 static void init_pthread_gc_support(void); | 64 static void init_pthread_gc_support(void); |
| 64 | 65 |
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 * | 973 * |
| 973 * NB: The destructor logic seems to have a bug so it isn't used. | 974 * NB: The destructor logic seems to have a bug so it isn't used. |
| 974 * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998. | 975 * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998. |
| 975 * More info - the problem is that pthreads calls the destructor | 976 * More info - the problem is that pthreads calls the destructor |
| 976 * eagerly as the thread returns from its root, rather than lazily | 977 * eagerly as the thread returns from its root, rather than lazily |
| 977 * after the thread is joined. Therefore, threads that are joining | 978 * after the thread is joined. Therefore, threads that are joining |
| 978 * and holding PRThread references are actually holding pointers to | 979 * and holding PRThread references are actually holding pointers to |
| 979 * nothing. | 980 * nothing. |
| 980 */ | 981 */ |
| 981 rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death); | 982 rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death); |
| 983 if (0 != rv) |
| 984 PR_Assert("0 == rv", __FILE__, __LINE__); |
| 985 pt_book.keyCreated = PR_TRUE; |
| 986 rv = pthread_setspecific(pt_book.key, thred); |
| 982 PR_ASSERT(0 == rv); | 987 PR_ASSERT(0 == rv); |
| 983 rv = pthread_setspecific(pt_book.key, thred); | |
| 984 PR_ASSERT(0 == rv); | |
| 985 } /* _PR_InitThreads */ | 988 } /* _PR_InitThreads */ |
| 986 | 989 |
| 987 #ifdef __GNUC__ | 990 #ifdef __GNUC__ |
| 988 /* | 991 /* |
| 989 * GCC supports the constructor and destructor attributes as of | 992 * GCC supports the constructor and destructor attributes as of |
| 990 * version 2.5. | 993 * version 2.5. |
| 991 */ | 994 */ |
| 992 static void _PR_Fini(void) __attribute__ ((destructor)); | 995 static void _PR_Fini(void) __attribute__ ((destructor)); |
| 993 #elif defined(__SUNPRO_C) | 996 #elif defined(__SUNPRO_C) |
| 994 /* | 997 /* |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 #endif | 1037 #endif |
| 1035 #elif defined(AIX) | 1038 #elif defined(AIX) |
| 1036 /* Need to use the -binitfini::_PR_Fini linker option. */ | 1039 /* Need to use the -binitfini::_PR_Fini linker option. */ |
| 1037 #endif | 1040 #endif |
| 1038 | 1041 |
| 1039 void _PR_Fini(void) | 1042 void _PR_Fini(void) |
| 1040 { | 1043 { |
| 1041 void *thred; | 1044 void *thred; |
| 1042 int rv; | 1045 int rv; |
| 1043 | 1046 |
| 1044 if (!_pr_initialized) return; | 1047 if (!_pr_initialized) { |
| 1048 /* Either NSPR was never successfully initialized or |
| 1049 * PR_Cleanup has been called already. */ |
| 1050 if (pt_book.keyCreated) |
| 1051 { |
| 1052 rv = pthread_key_delete(pt_book.key); |
| 1053 PR_ASSERT(0 == rv); |
| 1054 pt_book.keyCreated = PR_FALSE; |
| 1055 } |
| 1056 return; |
| 1057 } |
| 1045 | 1058 |
| 1046 _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); | 1059 _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); |
| 1047 if (NULL != thred) | 1060 if (NULL != thred) |
| 1048 { | 1061 { |
| 1049 /* | 1062 /* |
| 1050 * PR_FALSE, because it is unsafe to call back to the | 1063 * PR_FALSE, because it is unsafe to call back to the |
| 1051 * thread private data destructors at final cleanup. | 1064 * thread private data destructors at final cleanup. |
| 1052 */ | 1065 */ |
| 1053 _pt_thread_death_internal(thred, PR_FALSE); | 1066 _pt_thread_death_internal(thred, PR_FALSE); |
| 1054 rv = pthread_setspecific(pt_book.key, NULL); | 1067 rv = pthread_setspecific(pt_book.key, NULL); |
| 1055 PR_ASSERT(0 == rv); | 1068 PR_ASSERT(0 == rv); |
| 1056 } | 1069 } |
| 1057 rv = pthread_key_delete(pt_book.key); | 1070 rv = pthread_key_delete(pt_book.key); |
| 1058 PR_ASSERT(0 == rv); | 1071 PR_ASSERT(0 == rv); |
| 1072 pt_book.keyCreated = PR_FALSE; |
| 1059 /* TODO: free other resources used by NSPR */ | 1073 /* TODO: free other resources used by NSPR */ |
| 1060 /* _pr_initialized = PR_FALSE; */ | 1074 /* _pr_initialized = PR_FALSE; */ |
| 1061 } /* _PR_Fini */ | 1075 } /* _PR_Fini */ |
| 1062 | 1076 |
| 1063 PR_IMPLEMENT(PRStatus) PR_Cleanup(void) | 1077 PR_IMPLEMENT(PRStatus) PR_Cleanup(void) |
| 1064 { | 1078 { |
| 1065 PRThread *me = PR_GetCurrentThread(); | 1079 PRThread *me = PR_GetCurrentThread(); |
| 1066 int rv; | 1080 int rv; |
| 1067 PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); | 1081 PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR")); |
| 1068 PR_ASSERT(me->state & PT_THREAD_PRIMORD); | 1082 PR_ASSERT(me->state & PT_THREAD_PRIMORD); |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1774 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) | 1788 PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) |
| 1775 { | 1789 { |
| 1776 if (!thread) | 1790 if (!thread) |
| 1777 return NULL; | 1791 return NULL; |
| 1778 return thread->name; | 1792 return thread->name; |
| 1779 } | 1793 } |
| 1780 | 1794 |
| 1781 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ | 1795 #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ |
| 1782 | 1796 |
| 1783 /* ptthread.c */ | 1797 /* ptthread.c */ |
| OLD | NEW |