diff --git a/nsprpub/TAG-INFO b/nsprpub/TAG-INFO index 4436a363173..a5fbfe55505 100644 --- a/nsprpub/TAG-INFO +++ b/nsprpub/TAG-INFO @@ -1 +1 @@ -NSPR_4_9_1_RTM +NSPR_4_9_2_BETA1 diff --git a/nsprpub/admin/repackage.sh b/nsprpub/admin/repackage.sh index 8a2b367a4f8..2f84803c8e3 100755 --- a/nsprpub/admin/repackage.sh +++ b/nsprpub/admin/repackage.sh @@ -32,10 +32,10 @@ # # ------------------------------------------------------------------ -FROMTOP=/share/builds/components/nspr20/v4.9.1 -TOTOP=./v4.9.1 -NSPRDIR=nspr-4.9.1 -SOURCETAG=NSPR_4_9_1_RTM +FROMTOP=/share/builds/components/nspr20/v4.9.2 +TOTOP=./v4.9.2 +NSPRDIR=nspr-4.9.2 +SOURCETAG=NSPR_4_9_2_RTM # # enumerate Unix object directories on /s/b/c diff --git a/nsprpub/config/prdepend.h b/nsprpub/config/prdepend.h index 6c66b37ca0f..e49e92677e3 100644 --- a/nsprpub/config/prdepend.h +++ b/nsprpub/config/prdepend.h @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/nsprpub/configure b/nsprpub/configure index 140225c1a32..7493615cb69 100755 --- a/nsprpub/configure +++ b/nsprpub/configure @@ -736,7 +736,7 @@ test "$host_alias" != "$target_alias" && MOD_MAJOR_VERSION=4 MOD_MINOR_VERSION=9 -MOD_PATCH_VERSION=1 +MOD_PATCH_VERSION=2 NSPR_MODNAME=nspr20 _HAVE_PTHREADS= USE_PTHREADS= diff --git a/nsprpub/configure.in b/nsprpub/configure.in index 285506df8bc..da7961c9a72 100644 --- a/nsprpub/configure.in +++ b/nsprpub/configure.in @@ -15,7 +15,7 @@ dnl = Defaults dnl ======================================================== MOD_MAJOR_VERSION=4 MOD_MINOR_VERSION=9 -MOD_PATCH_VERSION=1 +MOD_PATCH_VERSION=2 NSPR_MODNAME=nspr20 _HAVE_PTHREADS= USE_PTHREADS= diff --git a/nsprpub/pr/include/md/_win95.h b/nsprpub/pr/include/md/_win95.h index b3b88bd3d6b..a919e3a02e6 100644 --- a/nsprpub/pr/include/md/_win95.h +++ b/nsprpub/pr/include/md/_win95.h @@ -362,6 +362,7 @@ extern PROsfd _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, #define _MD_CREATE_THREAD _PR_MD_CREATE_THREAD #define _MD_YIELD _PR_MD_YIELD #define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY +#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME #define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD #define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK #define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK diff --git a/nsprpub/pr/include/md/_winnt.h b/nsprpub/pr/include/md/_winnt.h index 57423eacd9a..4d4d2c12709 100644 --- a/nsprpub/pr/include/md/_winnt.h +++ b/nsprpub/pr/include/md/_winnt.h @@ -376,6 +376,7 @@ extern int _PR_NTFiberSafeSelect(int, fd_set *, fd_set *, fd_set *, #define _MD_END_THREAD _PR_MD_END_THREAD #define _MD_YIELD _PR_MD_YIELD #define _MD_SET_PRIORITY _PR_MD_SET_PRIORITY +#define _MD_SET_CURRENT_THREAD_NAME _PR_MD_SET_CURRENT_THREAD_NAME #define _MD_CLEAN_THREAD _PR_MD_CLEAN_THREAD #define _MD_SETTHREADAFFINITYMASK _PR_MD_SETTHREADAFFINITYMASK #define _MD_GETTHREADAFFINITYMASK _PR_MD_GETTHREADAFFINITYMASK diff --git a/nsprpub/pr/include/prinit.h b/nsprpub/pr/include/prinit.h index edbb2af4c96..c1100997319 100644 --- a/nsprpub/pr/include/prinit.h +++ b/nsprpub/pr/include/prinit.h @@ -31,11 +31,11 @@ PR_BEGIN_EXTERN_C ** The format of the version string is ** ".[.] []" */ -#define PR_VERSION "4.9.1" +#define PR_VERSION "4.9.2 Beta" #define PR_VMAJOR 4 #define PR_VMINOR 9 -#define PR_VPATCH 1 -#define PR_BETA PR_FALSE +#define PR_VPATCH 2 +#define PR_BETA PR_TRUE /* ** PRVersionCheck diff --git a/nsprpub/pr/include/private/primpl.h b/nsprpub/pr/include/private/primpl.h index d86f66f71b3..e9217f29db7 100644 --- a/nsprpub/pr/include/private/primpl.h +++ b/nsprpub/pr/include/private/primpl.h @@ -977,6 +977,9 @@ extern void _PR_MD_YIELD(void); extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri); #define _PR_MD_SET_PRIORITY _MD_SET_PRIORITY +extern void _PR_MD_SET_CURRENT_THREAD_NAME(const char *name); +#define _PR_MD_SET_CURRENT_THREAD_NAME _MD_SET_CURRENT_THREAD_NAME + NSPR_API(void) _PR_MD_SUSPENDALL(void); #define _PR_MD_SUSPENDALL _MD_SUSPENDALL @@ -1533,6 +1536,7 @@ struct PRThread { PRIntn errorStringLength; /* textLength from last call to PR_SetErrorText() */ PRInt32 errorStringSize; /* malloc()'d size of buffer | zero */ char *errorString; /* current error string | NULL */ + char *name; /* thread's name */ #if defined(_PR_PTHREADS) pthread_t id; /* pthread identifier for the thread */ diff --git a/nsprpub/pr/include/prthread.h b/nsprpub/pr/include/prthread.h index f38ff69c8d9..708c889c74b 100644 --- a/nsprpub/pr/include/prthread.h +++ b/nsprpub/pr/include/prthread.h @@ -144,6 +144,17 @@ NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread); */ NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority); +/* +** Set the name of the current thread, which will be visible in a debugger +** and accessible via a call to PR_GetThreadName(). +*/ +NSPR_API(PRStatus) PR_SetCurrentThreadName(const char *name); + +/* +** Return the name of "thread", if set. Otherwise return NULL. +*/ +NSPR_API(const char *) PR_GetThreadName(const PRThread *thread); + /* ** This routine returns a new index for per-thread-private data table. ** The index is visible to all threads within a process. This index can diff --git a/nsprpub/pr/src/md/windows/ntthread.c b/nsprpub/pr/src/md/windows/ntthread.c index 5f9e646377e..d695fe40e85 100644 --- a/nsprpub/pr/src/md/windows/ntthread.c +++ b/nsprpub/pr/src/md/windows/ntthread.c @@ -276,6 +276,40 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) return; } +const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void +_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) +{ + THREADNAME_INFO info; + + if (!IsDebuggerPresent()) + return; + + info.dwType = 0x1000; + info.szName = (char*) name; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(MS_VC_EXCEPTION, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR*)&info); + } __except(EXCEPTION_CONTINUE_EXECUTION) { + } +} + void _PR_MD_CLEAN_THREAD(PRThread *thread) { diff --git a/nsprpub/pr/src/md/windows/w95thred.c b/nsprpub/pr/src/md/windows/w95thred.c index dc0eac31bcf..21b4a6eac25 100644 --- a/nsprpub/pr/src/md/windows/w95thred.c +++ b/nsprpub/pr/src/md/windows/w95thred.c @@ -168,6 +168,40 @@ _PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri) return; } +const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void +_PR_MD_SET_CURRENT_THREAD_NAME(const char *name) +{ + THREADNAME_INFO info; + + if (!IsDebuggerPresent()) + return; + + info.dwType = 0x1000; + info.szName = (char*) name; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(MS_VC_EXCEPTION, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR*)&info); + } __except(EXCEPTION_CONTINUE_EXECUTION) { + } +} + void _PR_MD_CLEAN_THREAD(PRThread *thread) { diff --git a/nsprpub/pr/src/nspr.def b/nsprpub/pr/src/nspr.def index c6618a8d444..7777a3dbe33 100644 --- a/nsprpub/pr/src/nspr.def +++ b/nsprpub/pr/src/nspr.def @@ -446,3 +446,8 @@ EXPORTS ;- ;+ global: PR_GetVersion; ;+} NSPR_4.8; +;+NSPR_4.9.2 { +;+ global: + PR_GetThreadName; + PR_SetCurrentThreadName; +;+} NSPR_4.8.9; diff --git a/nsprpub/pr/src/pthreads/ptthread.c b/nsprpub/pr/src/pthreads/ptthread.c index c3223bbedab..34c0bb12dca 100644 --- a/nsprpub/pr/src/pthreads/ptthread.c +++ b/nsprpub/pr/src/pthreads/ptthread.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef SYMBIAN /* In Open C sched_get_priority_min/max do not work properly, so we undefine @@ -794,6 +795,8 @@ static void _pt_thread_death_internal(void *arg, PRBool callDestructors) PR_Free(thred->privateData); if (NULL != thred->errorString) PR_Free(thred->errorString); + if (NULL != thred->name) + PR_Free(thred->name); PR_Free(thred->stack); if (NULL != thred->syspoll_list) PR_Free(thred->syspoll_list); @@ -1612,6 +1615,76 @@ PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred) #endif /* !defined(_PR_DCETHREADS) */ +PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) +{ + PRThread *thread; + size_t nameLen; + int result; + + if (!name) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + thread = PR_GetCurrentThread(); + if (!thread) + return PR_FAILURE; + + PR_Free(thread->name); + nameLen = strlen(name) + 1; + thread->name = (char *)PR_Malloc(nameLen); + if (!thread->name) + return PR_FAILURE; + memcpy(thread->name, name, nameLen); + +#if defined(OPENBSD) || defined(FREEBSD) + result = pthread_set_name_np(thread->id, name); +#else /* not BSD */ + /* + * On OSX, pthread_setname_np is only available in 10.6 or later, so test + * for it at runtime. It also may not be available on all linux distros. + * The name length limit is 16 bytes. + */ +#if defined(DARWIN) + int (*dynamic_pthread_setname_np)(const char*); +#else + int (*dynamic_pthread_setname_np)(pthread_t, const char*); +#endif + + *(void**)(&dynamic_pthread_setname_np) = + dlsym(RTLD_DEFAULT, "pthread_setname_np"); + if (!dynamic_pthread_setname_np) + return PR_SUCCESS; + +#define SETNAME_LENGTH_CONSTRAINT 15 + char name_dup[SETNAME_LENGTH_CONSTRAINT + 1]; + if (nameLen > SETNAME_LENGTH_CONSTRAINT + 1) { + memcpy(name_dup, name, SETNAME_LENGTH_CONSTRAINT); + name_dup[SETNAME_LENGTH_CONSTRAINT] = '\0'; + name = name_dup; + } + +#if defined(DARWIN) + result = dynamic_pthread_setname_np(name); +#else + result = dynamic_pthread_setname_np(thread->id, name); +#endif +#endif /* not BSD */ + + if (result) { + PR_SetError(PR_UNKNOWN_ERROR, result); + return PR_FAILURE; + } + return PR_SUCCESS; +} + +PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) +{ + if (!thread) + return NULL; + return thread->name; +} + #endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */ /* ptthread.c */ diff --git a/nsprpub/pr/src/threads/combined/pruthr.c b/nsprpub/pr/src/threads/combined/pruthr.c index 53eea1fc488..fa5f5209854 100644 --- a/nsprpub/pr/src/threads/combined/pruthr.c +++ b/nsprpub/pr/src/threads/combined/pruthr.c @@ -237,6 +237,7 @@ static void _PR_InitializeRecycledThread(PRThread *thread) PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0); PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0); PR_ASSERT(thread->errorStringLength == 0); + PR_ASSERT(thread->name == 0); /* Reset data members in thread structure */ thread->errorCode = thread->osErrorCode = 0; @@ -1581,6 +1582,37 @@ PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread, } else _PR_SetThreadPriority(thread, newPri); } +PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name) +{ + PRThread *thread; + size_t nameLen; + + if (!name) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + + thread = PR_GetCurrentThread(); + if (!thread) + return PR_FAILURE; + + PR_Free(thread->name); + nameLen = strlen(name) + 1; + thread->name = (char *)PR_Malloc(nameLen); + if (!thread->name) + return PR_FAILURE; + memcpy(thread->name, name, nameLen); + _PR_MD_SET_CURRENT_THREAD_NAME(thread->name); + return PR_SUCCESS; +} + +PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread) +{ + if (!thread) + return NULL; + return thread->name; +} + /* ** This routine prevents all other threads from running. This call is needed by diff --git a/nsprpub/pr/src/threads/prcthr.c b/nsprpub/pr/src/threads/prcthr.c index 4f9a3beb446..268814473e1 100644 --- a/nsprpub/pr/src/threads/prcthr.c +++ b/nsprpub/pr/src/threads/prcthr.c @@ -35,6 +35,7 @@ void _PR_CleanupThread(PRThread *thread) } thread->dump = 0; + PR_DELETE(thread->name); PR_DELETE(thread->errorString); thread->errorStringSize = 0; thread->errorStringLength = 0; diff --git a/nsprpub/pr/tests/vercheck.c b/nsprpub/pr/tests/vercheck.c index 415caae05e1..2f42523b52f 100644 --- a/nsprpub/pr/tests/vercheck.c +++ b/nsprpub/pr/tests/vercheck.c @@ -20,9 +20,10 @@ #include /* - * This release (4.9.1) is backward compatible with the + * This release (4.9.2) is backward compatible with the * 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, 4.6.x, 4.7.x, - * 4.8.x, and 4.9 releases. It, of course, is compatible with itself. + * 4.8.x, 4.9, and 4.9.1 releases. It, of course, + * is compatible with itself. */ static char *compatible_version[] = { "4.0", "4.0.1", "4.1", "4.1.1", "4.1.2", "4.1.3", @@ -34,7 +35,7 @@ static char *compatible_version[] = { "4.7.6", "4.8", "4.8.1", "4.8.2", "4.8.3", "4.8.4", "4.8.5", "4.8.6", "4.8.7", "4.8.8", "4.8.9", - "4.9", PR_VERSION + "4.9", "4.9.1", PR_VERSION }; /* @@ -49,7 +50,7 @@ static char *incompatible_version[] = { "3.0", "3.0.1", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.5", "3.5.1", - "4.9.2", + "4.9.3", "4.10", "4.10.1", "10.0", "11.1", "12.14.20" };