Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread naming #31

Open
JanPlitzkow opened this issue May 2, 2017 · 1 comment
Open

Thread naming #31

JanPlitzkow opened this issue May 2, 2017 · 1 comment

Comments

@JanPlitzkow
Copy link
Contributor

Hi,
while developing multi-thread applications naming of threads (e.g. for debugging) has proven to be quite useful. In the following I'd like to propose some additions to your library. Use them if you like them, feel free to simply close this issue if you think otherwise...

Header threadName.h would be:

#ifndef THREAD_NAME_H_
#define THREAD_NAME_H_

#include <thread>

namespace misc
{
	/// name current thread
	void SetThreadName(const std::string& threadName);

	/// name thread identified by thread-handle
	void SetThreadName(std::thread& thread, const std::string& threadName);
}

#endif /* THREAD_NAME_H_ */

Source threadName.cpp would be the following, where the windows part is mainly based on this MSDN example (it appears "dirty", but I didn't find any cleaner solution):

#include "anyrpc/threadName.h"

#ifdef _WIN32 /* WINDOWS */

	#include <windows.h>  
	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 SetThreadName(DWORD dwThreadID, const char* threadName) {
		THREADNAME_INFO info;
		info.dwType = 0x1000;
		info.szName = threadName;
		info.dwThreadID = dwThreadID;
		info.dwFlags = 0;
	#pragma warning(push)  
	#pragma warning(disable: 6320 6322)  
		__try
		{
			RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
		}
	#pragma warning(pop)  
	}

	namespace misc
	{
		void SetThreadName(const std::string& threadName)
		{
			::SetThreadName(GetCurrentThreadId(), threadName.c_str());
		}

		void SetThreadName(std::thread& thread, const std::string& threadName)
		{
			DWORD threadId = ::GetThreadId(static_cast<HANDLE>(thread.native_handle()));
			::SetThreadName(threadId, threadName.c_str());
		}
	}

#else /* LINUX */

	#include <sys/prctl.h>

	namespace misc
	{
		void SetThreadName(const std::string& threadName)
		{
			::prctl(PR_SET_NAME, threadName.c_str(), 0, 0, 0);
		}

		void SetThreadName(std::thread& thread, const std::string& threadName)
		{
			auto handle = thread.native_handle();
			::pthread_setname_np(handle, threadName.c_str());
		}
	}

#endif

Obviously this is not for MacOS yet...

Using the above header and source one could for example add this line to StartThread() in server.cpp:

misc::SetThreadName(thread_, "AnyRpcServer");

Adding such a line to all thread creations allows an easy recognition of different threads in a multi-thread-environment and also thread-name-dependent breakpoints (the latter at least in VS).

@JanPlitzkow
Copy link
Contributor Author

I hope this issue is visible for you, my "account has been flagged" the last days. I've contacted the GitHub Team and they now have reset my account. An "overzealous spam-detecting robot" seems to have been the problem... :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant