mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-25 16:13:42 +01:00
set thread name (#3664)
* set thread name * fix dead lock * fix code style & return fake name * fix code style * fix code style Co-authored-by: Aleksandar Fabijanic <aleks-f@users.noreply.github.com>
This commit is contained in:
parent
2a36359bc7
commit
1d28d2d42d
@ -52,6 +52,11 @@
|
||||
#define POCO_THREAD_STACK_SIZE 0
|
||||
#endif
|
||||
|
||||
// Defined to desired max thread name length
|
||||
#ifndef POCO_MAX_THREAD_NAME_LEN
|
||||
#define POCO_MAX_THREAD_NAME_LEN 15
|
||||
#endif
|
||||
|
||||
|
||||
// Define to override system-provided
|
||||
// minimum thread priority value on POSIX
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
|
||||
void setName(const std::string& name);
|
||||
/// Sets the name of the thread.
|
||||
/// Note that it only take effect before start method invoked.
|
||||
|
||||
void setPriority(Priority prio);
|
||||
/// Sets the thread's priority.
|
||||
@ -275,10 +276,8 @@ private:
|
||||
Thread& operator = (const Thread&);
|
||||
|
||||
int _id;
|
||||
std::string _name;
|
||||
ThreadLocalStorage* _pTLS;
|
||||
Event _event;
|
||||
mutable FastMutex _mutex;
|
||||
|
||||
friend class ThreadLocalStorage;
|
||||
friend class PooledThread;
|
||||
@ -302,17 +301,13 @@ inline int Thread::id() const
|
||||
|
||||
inline std::string Thread::name() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _name;
|
||||
return getNameImpl();
|
||||
}
|
||||
|
||||
|
||||
inline std::string Thread::getName() const
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
return _name;
|
||||
return getNameImpl();
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,10 +36,8 @@
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class Foundation_API ThreadImpl
|
||||
{
|
||||
public:
|
||||
@ -64,6 +62,12 @@ public:
|
||||
~ThreadImpl();
|
||||
|
||||
TIDImpl tidImpl() const;
|
||||
void setNameImpl(const std::string& threadName);
|
||||
std::string getNameImpl() const;
|
||||
std::string getOSThreadNameImpl();
|
||||
/// Returns the thread's name, expressed as an operating system
|
||||
/// specific name value. Return empty string if thread is not running.
|
||||
/// For test used only.
|
||||
void setPriorityImpl(int prio);
|
||||
int getPriorityImpl() const;
|
||||
void setOSPriorityImpl(int prio, int policy = SCHED_OTHER);
|
||||
@ -141,6 +145,7 @@ private:
|
||||
std::size_t stackSize;
|
||||
bool started;
|
||||
bool joined;
|
||||
std::string name;
|
||||
mutable FastMutex mutex;
|
||||
};
|
||||
|
||||
|
@ -70,6 +70,12 @@ public:
|
||||
~ThreadImpl();
|
||||
|
||||
TIDImpl tidImpl() const;
|
||||
void setNameImpl(const std::string& threadName);
|
||||
std::string getNameImpl() const;
|
||||
std::string getOSThreadNameImpl();
|
||||
/// Returns the thread's name, expressed as an operating system
|
||||
/// specific name value. Return empty string if thread is not running.
|
||||
/// For test used only.
|
||||
void setPriorityImpl(int prio);
|
||||
int getPriorityImpl() const;
|
||||
void setOSPriorityImpl(int prio, int policy = 0);
|
||||
@ -111,11 +117,12 @@ protected:
|
||||
|
||||
Runnable* pRunnableTarget;
|
||||
AutoPtr<CallbackData> pCallbackTarget;
|
||||
int task;
|
||||
int prio;
|
||||
int osPrio;
|
||||
Event done;
|
||||
int stackSize;
|
||||
int task;
|
||||
int prio;
|
||||
int osPrio;
|
||||
Event done;
|
||||
int stackSize;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -57,6 +57,12 @@ public:
|
||||
~ThreadImpl();
|
||||
|
||||
TIDImpl tidImpl() const;
|
||||
void setNameImpl(const std::string& threadName);
|
||||
std::string getNameImpl() const;
|
||||
std::string getOSThreadNameImpl();
|
||||
/// Returns the thread's name, expressed as an operating system
|
||||
/// specific name value. Return empty string if thread is not running.
|
||||
/// For test used only.
|
||||
void setPriorityImpl(int prio);
|
||||
int getPriorityImpl() const;
|
||||
void setOSPriorityImpl(int prio, int policy = 0);
|
||||
@ -116,6 +122,7 @@ private:
|
||||
DWORD _threadId;
|
||||
int _prio;
|
||||
int _stackSize;
|
||||
std::string _name;
|
||||
|
||||
static CurrentThreadHolder _currentThreadHolder;
|
||||
};
|
||||
|
@ -57,6 +57,12 @@ public:
|
||||
~ThreadImpl();
|
||||
|
||||
TIDImpl tidImpl() const;
|
||||
void setNameImpl(const std::string& threadName);
|
||||
std::string getNameImpl() const;
|
||||
std::string getOSThreadNameImpl();
|
||||
/// Returns the thread's name, expressed as an operating system
|
||||
/// specific name value. Return empty string if thread is not running.
|
||||
/// For test used only.
|
||||
void setPriorityImpl(int prio);
|
||||
int getPriorityImpl() const;
|
||||
void setOSPriorityImpl(int prio, int policy = 0);
|
||||
@ -112,6 +118,7 @@ private:
|
||||
DWORD _threadId;
|
||||
int _prio;
|
||||
int _stackSize;
|
||||
std::string _name;
|
||||
|
||||
static CurrentThreadHolder _currentThreadHolder;
|
||||
};
|
||||
|
@ -90,19 +90,19 @@ private:
|
||||
|
||||
Thread::Thread():
|
||||
_id(uniqueId()),
|
||||
_name(makeName()),
|
||||
_pTLS(0),
|
||||
_event(true)
|
||||
{
|
||||
setNameImpl(makeName());
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(const std::string& name):
|
||||
_id(uniqueId()),
|
||||
_name(name),
|
||||
_pTLS(0),
|
||||
_event(true)
|
||||
{
|
||||
setNameImpl(name);
|
||||
}
|
||||
|
||||
|
||||
@ -210,9 +210,7 @@ int Thread::uniqueId()
|
||||
|
||||
void Thread::setName(const std::string& name)
|
||||
{
|
||||
FastMutex::ScopedLock lock(_mutex);
|
||||
|
||||
_name = name;
|
||||
setNameImpl(name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,21 +62,25 @@ namespace
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
void setThreadName(pthread_t thread, const std::string& threadName)
|
||||
namespace
|
||||
{
|
||||
#if (POCO_OS == POCO_OS_MAC_OS_X)
|
||||
pthread_setname_np(threadName.c_str()); // __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
|
||||
#else
|
||||
if (pthread_setname_np(thread, threadName.c_str()) == ERANGE && threadName.size() > 15)
|
||||
void setThreadName(const std::string& threadName)
|
||||
{
|
||||
std::string truncName(threadName, 0, 7);
|
||||
truncName.append("~");
|
||||
truncName.append(threadName, threadName.size() - 7, 7);
|
||||
pthread_setname_np(thread, truncName.c_str());
|
||||
}
|
||||
#if (POCO_OS == POCO_OS_MAC_OS_X)
|
||||
if (pthread_setname_np(threadName.c_str()))
|
||||
#else
|
||||
if (pthread_setname_np(pthread_self(), threadName.c_str()))
|
||||
#endif
|
||||
}
|
||||
throw Poco::SystemException("cannot get thread name");
|
||||
}
|
||||
|
||||
std::string getThreadName()
|
||||
{
|
||||
char name[POCO_MAX_THREAD_NAME_LEN + 1]{'\0'};
|
||||
if (pthread_getname_np(pthread_self(), name, POCO_MAX_THREAD_NAME_LEN + 1))
|
||||
throw Poco::SystemException("cannot get thread name");
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +104,44 @@ ThreadImpl::~ThreadImpl()
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadImpl::setNameImpl(const std::string& threadName)
|
||||
{
|
||||
std::string realName = threadName;
|
||||
#if (POCO_OS == POCO_OS_MAC_OS_X)
|
||||
if (threadName.size() > POCO_MAX_THREAD_NAME_LEN)
|
||||
{
|
||||
int half = (POCO_MAX_THREAD_NAME_LEN - 1) / 2;
|
||||
#else
|
||||
if (threadName.size() > std::min(POCO_MAX_THREAD_NAME_LEN, 15))
|
||||
{
|
||||
int half = (std::min(POCO_MAX_THREAD_NAME_LEN, 15) - 1) / 2;
|
||||
#endif
|
||||
std::string truncName(threadName, 0, half);
|
||||
truncName.append("~");
|
||||
truncName.append(threadName, threadName.size() - half);
|
||||
realName = truncName;
|
||||
}
|
||||
|
||||
ScopedLock<FastMutex> lock(_pData->mutex);
|
||||
if (realName != _pData->name)
|
||||
{
|
||||
_pData->name = realName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getNameImpl() const
|
||||
{
|
||||
ScopedLock<FastMutex> lock(_pData->mutex);
|
||||
return _pData->name;
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getOSThreadNameImpl()
|
||||
{
|
||||
return isRunningImpl() ? getThreadName() : "";
|
||||
}
|
||||
|
||||
|
||||
void ThreadImpl::setPriorityImpl(int prio)
|
||||
{
|
||||
@ -350,9 +392,14 @@ void* ThreadImpl::runnableEntry(void* pThread)
|
||||
pthread_sigmask(SIG_BLOCK, &sset, 0);
|
||||
#endif
|
||||
|
||||
ThreadImpl* pThreadImpl = reinterpret_cast<ThreadImpl*>(pThread);
|
||||
setThreadName(pThreadImpl->_pData->thread, reinterpret_cast<Thread*>(pThread)->getName());
|
||||
auto* pThreadImpl = reinterpret_cast<ThreadImpl*>(pThread);
|
||||
AutoPtr<ThreadData> pData = pThreadImpl->_pData;
|
||||
|
||||
{
|
||||
FastMutex::ScopedLock lock(pData->mutex);
|
||||
setThreadName(pData->name);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pData->pRunnableTarget->run();
|
||||
|
@ -37,6 +37,38 @@ ThreadImpl::~ThreadImpl()
|
||||
}
|
||||
|
||||
|
||||
void ThreadImpl::setNameImpl(const std::string& threadName)
|
||||
{
|
||||
std::string realName = threadName;
|
||||
if (threadName.size() > POCO_MAX_THREAD_NAME_LEN)
|
||||
{
|
||||
int half = (POCO_MAX_THREAD_NAME_LEN - 1) / 2;
|
||||
std::string truncName(threadName, 0, half);
|
||||
truncName.append("~");
|
||||
truncName.append(threadName, threadName.size() - half);
|
||||
realName = truncName;
|
||||
}
|
||||
|
||||
if (realName != _pData->name)
|
||||
{
|
||||
_pData->name = realName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getNameImpl() const
|
||||
{
|
||||
return _pData->name;
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getOSThreadNameImpl()
|
||||
{
|
||||
// return fake thread name;
|
||||
return isRunningImpl() ? _pData->name : "";
|
||||
}
|
||||
|
||||
|
||||
void ThreadImpl::setPriorityImpl(int prio)
|
||||
{
|
||||
if (prio != _pData->prio)
|
||||
@ -141,7 +173,7 @@ ThreadImpl* ThreadImpl::currentImpl()
|
||||
|
||||
ThreadImpl::TIDImpl ThreadImpl::currentTidImpl()
|
||||
{
|
||||
return taskIdSelf();
|
||||
return taskIdSelf();
|
||||
}
|
||||
|
||||
long ThreadImpl::currentOsTidImpl()
|
||||
@ -181,6 +213,7 @@ void ThreadImpl::runnableEntry(void* pThread, int, int, int, int, int, int, int,
|
||||
_pCurrent = reinterpret_cast<ThreadImpl*>(pThread);
|
||||
|
||||
AutoPtr<ThreadData> pData = _pCurrent->_pData;
|
||||
|
||||
try
|
||||
{
|
||||
pData->pRunnableTarget->run();
|
||||
|
@ -18,9 +18,6 @@
|
||||
#include <process.h>
|
||||
|
||||
|
||||
#if defined(POCO_WIN32_DEBUGGER_THREAD_NAMES)
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
/// See <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>
|
||||
@ -38,29 +35,26 @@ namespace
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
void setThreadName(DWORD dwThreadID, const char* threadName)
|
||||
|
||||
void setThreadName(DWORD dwThreadID, const std::string& threadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName.c_str();
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
__try
|
||||
{
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
@ -82,6 +76,37 @@ ThreadImpl::~ThreadImpl()
|
||||
}
|
||||
|
||||
|
||||
void ThreadImpl::setNameImpl(const std::string& threadName)
|
||||
{
|
||||
std::string realName = threadName;
|
||||
if (threadName.size() > POCO_MAX_THREAD_NAME_LEN)
|
||||
{
|
||||
int half = (POCO_MAX_THREAD_NAME_LEN - 1) / 2;
|
||||
std::string truncName(threadName, 0, half);
|
||||
truncName.append("~");
|
||||
truncName.append(threadName, threadName.size() - half);
|
||||
realName = truncName;
|
||||
}
|
||||
|
||||
if (realName != _name)
|
||||
{
|
||||
_name = realName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getNameImpl() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
std::string ThreadImpl::getOSThreadNameImpl()
|
||||
{
|
||||
// return fake thread name
|
||||
return isRunningImpl() ? _name : "";
|
||||
}
|
||||
|
||||
|
||||
void ThreadImpl::setPriorityImpl(int prio)
|
||||
{
|
||||
if (prio != _prio)
|
||||
@ -200,10 +225,9 @@ DWORD WINAPI ThreadImpl::runnableEntry(LPVOID pThread)
|
||||
unsigned __stdcall ThreadImpl::runnableEntry(void* pThread)
|
||||
#endif
|
||||
{
|
||||
_currentThreadHolder.set(reinterpret_cast<ThreadImpl*>(pThread));
|
||||
#if defined(POCO_WIN32_DEBUGGER_THREAD_NAMES)
|
||||
setThreadName(-1, reinterpret_cast<Thread*>(pThread)->getName().c_str());
|
||||
#endif
|
||||
auto * pThreadImpl = reinterpret_cast<ThreadImpl*>(pThread);
|
||||
_currentThreadHolder.set(pThreadImpl);
|
||||
setThreadName(-1, pThreadImpl->_name);
|
||||
try
|
||||
{
|
||||
reinterpret_cast<ThreadImpl*>(pThread)->_pRunnableTarget->run();
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/ErrorHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
@ -38,6 +37,35 @@ ThreadImpl::~ThreadImpl()
|
||||
if (_thread) CloseHandle(_thread);
|
||||
}
|
||||
|
||||
void ThreadImpl::setNameImpl(const std::string& threadName)
|
||||
{
|
||||
std::string realName = threadName;
|
||||
if (threadName.size() > POCO_MAX_THREAD_NAME_LEN)
|
||||
{
|
||||
int half = (POCO_MAX_THREAD_NAME_LEN - 1) / 2;
|
||||
std::string truncName(threadName, 0, half);
|
||||
truncName.append("~");
|
||||
truncName.append(threadName, threadName.size() - half);
|
||||
realName = truncName;
|
||||
}
|
||||
|
||||
if (realName != _name)
|
||||
{
|
||||
_name = realName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ThreadImpl::getNameImpl() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
std::string ThreadImpl::getOSThreadNameImpl()
|
||||
{
|
||||
// return fake thread name;
|
||||
return isRunningImpl() ? _name : "";
|
||||
}
|
||||
|
||||
void ThreadImpl::setPriorityImpl(int prio)
|
||||
{
|
||||
|
@ -41,7 +41,11 @@ public:
|
||||
{
|
||||
Thread* pThread = Thread::current();
|
||||
if (pThread)
|
||||
{
|
||||
_threadName = pThread->name();
|
||||
auto *pThreadImpl = reinterpret_cast<Poco::ThreadImpl *>(pThread);
|
||||
_osThreadName = pThreadImpl->getOSThreadNameImpl();
|
||||
}
|
||||
_ran = true;
|
||||
_event.wait();
|
||||
}
|
||||
@ -56,6 +60,11 @@ public:
|
||||
return _threadName;
|
||||
}
|
||||
|
||||
const std::string& osThreadName() const
|
||||
{
|
||||
return _osThreadName;
|
||||
}
|
||||
|
||||
void notify()
|
||||
{
|
||||
_event.set();
|
||||
@ -71,6 +80,7 @@ public:
|
||||
private:
|
||||
bool _ran;
|
||||
std::string _threadName;
|
||||
std::string _osThreadName;
|
||||
Event _event;
|
||||
};
|
||||
|
||||
@ -168,6 +178,7 @@ void ThreadTest::testThread()
|
||||
assertTrue (!thread.isRunning());
|
||||
assertTrue (r.ran());
|
||||
assertTrue (!r.threadName().empty());
|
||||
assertTrue (!r.osThreadName().empty());
|
||||
}
|
||||
|
||||
|
||||
@ -180,6 +191,19 @@ void ThreadTest::testNamedThread()
|
||||
thread.join();
|
||||
assertTrue (r.ran());
|
||||
assertTrue (r.threadName() == "MyThread");
|
||||
assertTrue (r.osThreadName() == r.threadName());
|
||||
|
||||
// name len > POCO_MAX_THREAD_NAME_LEN
|
||||
Thread thread2("0123456789aaaaaaaaaa9876543210");
|
||||
MyRunnable r2;
|
||||
thread2.start(r2);
|
||||
r2.notify();
|
||||
thread2.join();
|
||||
assertTrue (r2.ran());
|
||||
assertTrue (r2.osThreadName() == r2.threadName());
|
||||
assertTrue (r2.threadName().length() <= POCO_MAX_THREAD_NAME_LEN);
|
||||
assertTrue (std::string(r2.threadName(), 0, 7) == "0123456");
|
||||
assertTrue (std::string(r2.threadName(), r2.threadName().size() - 7) == "6543210");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user