Bug 758837: add the PR_SetThreadName and PR_GetThreadName functions for

setting and getting the name of the current thread.  The patch is
contributed by Honza Bambas <<honzab.moz@firemni.cz>.  r=wtc.
Modified Files: prthread.h _win95.h _winnt.h primpl.h nspr.def ntthread.c
	w95thred.c ptthread.c prcthr.c pruthr.c


git-svn-id: svn://10.0.0.236/trunk@263855 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
wtc%google.com 2012-05-26 00:15:24 +00:00
parent 3b82024c06
commit 727b671f9c
10 changed files with 202 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -144,6 +144,17 @@ NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
*/
NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
/*
** Set the thread name, which will be visible in a debugger and accessible
** via a call to PR_GetThreadName().
*/
NSPR_API(PRStatus) PR_SetThreadName(const char *name);
/*
** Return the current thread name, if set. Otherwise return NULL.
*/
NSPR_API(const char *) PR_GetThreadName();
/*
** 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

View File

@ -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)
{

View File

@ -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)
{

View File

@ -446,3 +446,8 @@ EXPORTS ;-
;+ global:
PR_GetVersion;
;+} NSPR_4.8;
;+NSPR_4.9.1 {
;+ global:
PR_GetThreadName;
PR_SetThreadName;
;+} NSPR_4.8.9;

View File

@ -19,6 +19,7 @@
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <dlfcn.h>
#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,79 @@ PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred)
#endif /* !defined(_PR_DCETHREADS) */
PR_IMPLEMENT(PRStatus) PR_SetThreadName(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()
{
PRThread *thread;
thread = PR_GetCurrentThread();
if (!thread)
return NULL;
return thread->name;
}
#endif /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
/* ptthread.c */

View File

@ -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,40 @@ PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread,
} else _PR_SetThreadPriority(thread, newPri);
}
PR_IMPLEMENT(PRStatus) PR_SetThreadName(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()
{
PRThread *thread;
thread = PR_GetCurrentThread();
if (!thread)
return NULL;
return thread->name;
}
/*
** This routine prevents all other threads from running. This call is needed by

View File

@ -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;