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:
parent
3b82024c06
commit
727b671f9c
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -446,3 +446,8 @@ EXPORTS ;-
|
||||
;+ global:
|
||||
PR_GetVersion;
|
||||
;+} NSPR_4.8;
|
||||
;+NSPR_4.9.1 {
|
||||
;+ global:
|
||||
PR_GetThreadName;
|
||||
PR_SetThreadName;
|
||||
;+} NSPR_4.8.9;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user