mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-26 23:01:04 +08:00
Implement thread name on windows, cleanup thread naming internals
This commit is contained in:
parent
046ccfc408
commit
27005cc1ae
@ -426,14 +426,10 @@ void zmq::thread_ctx_t::start_thread (thread_t &thread_,
|
||||
_thread_affinity_cpus);
|
||||
|
||||
char namebuf[16] = "";
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
LIBZMQ_UNUSED (name_);
|
||||
#else
|
||||
snprintf (namebuf, sizeof (namebuf), "%s%sZMQbg%s%s",
|
||||
_thread_name_prefix.empty () ? "" : _thread_name_prefix.c_str (),
|
||||
_thread_name_prefix.empty () ? "" : "/", name_ ? "/" : "",
|
||||
name_ ? name_ : "");
|
||||
#endif
|
||||
thread_.start (tfn_, arg_, namebuf);
|
||||
}
|
||||
|
||||
|
@ -57,10 +57,8 @@ zmq::io_thread_t::~io_thread_t ()
|
||||
void zmq::io_thread_t::start ()
|
||||
{
|
||||
char name[16] = "";
|
||||
#ifndef ZMQ_HAVE_WINDOWS
|
||||
snprintf (name, sizeof (name), "IO/%u",
|
||||
get_tid () - zmq::ctx_t::reaper_tid - 1);
|
||||
#endif
|
||||
// Start the underlying I/O thread.
|
||||
_poller->start (name);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ static unsigned int __stdcall thread_routine (void *arg_)
|
||||
#endif
|
||||
{
|
||||
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
||||
self->applyThreadName ();
|
||||
self->_tfn (self->_arg);
|
||||
return 0;
|
||||
}
|
||||
@ -54,9 +55,10 @@ static unsigned int __stdcall thread_routine (void *arg_)
|
||||
|
||||
void zmq::thread_t::start (thread_fn *tfn_, void *arg_, const char *name_)
|
||||
{
|
||||
LIBZMQ_UNUSED (name_);
|
||||
_tfn = tfn_;
|
||||
_arg = arg_;
|
||||
if (name_)
|
||||
strncpy (_name, name_, sizeof (_name));
|
||||
#if defined _WIN32_WCE
|
||||
_descriptor =
|
||||
(HANDLE) CreateThread (NULL, 0, &::thread_routine, this, 0, NULL);
|
||||
@ -92,10 +94,48 @@ void zmq::thread_t::setSchedulingParameters (
|
||||
LIBZMQ_UNUSED (affinity_cpus_);
|
||||
}
|
||||
|
||||
void zmq::thread_t::setThreadName (const char *name_)
|
||||
void zmq::thread_t::
|
||||
applySchedulingParameters () // to be called in secondary thread context
|
||||
{
|
||||
// not implemented
|
||||
LIBZMQ_UNUSED (name_);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
#pragma pack(push, 8)
|
||||
struct thread_info_t
|
||||
{
|
||||
DWORD _type;
|
||||
LPCSTR _name;
|
||||
DWORD _thread_id;
|
||||
DWORD _flags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
|
||||
void zmq::thread_t::
|
||||
applyThreadName () // to be called in secondary thread context
|
||||
{
|
||||
if (!_name[0])
|
||||
return;
|
||||
|
||||
thread_info_t thread_info;
|
||||
thread_info._type = 0x1000;
|
||||
thread_info._name = _name;
|
||||
thread_info._thread_id = -1;
|
||||
thread_info._flags = 0;
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 6320 6322)
|
||||
__try {
|
||||
DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
RaiseException (MS_VC_EXCEPTION, 0,
|
||||
sizeof (thread_info) / sizeof (ULONG_PTR),
|
||||
(ULONG_PTR *) &thread_info);
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION) {
|
||||
}
|
||||
#pragma warning(pop)
|
||||
}
|
||||
|
||||
#elif defined ZMQ_HAVE_VXWORKS
|
||||
@ -154,10 +194,10 @@ void zmq::thread_t::
|
||||
}
|
||||
}
|
||||
|
||||
void zmq::thread_t::setThreadName (const char *name_)
|
||||
void zmq::thread_t::
|
||||
applyThreadName () // to be called in secondary thread context
|
||||
{
|
||||
// not implemented
|
||||
LIBZMQ_UNUSED (name_);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -181,7 +221,7 @@ static void *thread_routine (void *arg_)
|
||||
#endif
|
||||
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
||||
self->applySchedulingParameters ();
|
||||
self->setThreadName (self->_name.c_str ());
|
||||
self->applyThreadName ();
|
||||
self->_tfn (self->_arg);
|
||||
return NULL;
|
||||
}
|
||||
@ -191,7 +231,8 @@ void zmq::thread_t::start (thread_fn *tfn_, void *arg_, const char *name_)
|
||||
{
|
||||
_tfn = tfn_;
|
||||
_arg = arg_;
|
||||
_name = name_;
|
||||
if (name_)
|
||||
strncpy (_name, name_, sizeof (_name));
|
||||
int rc = pthread_create (&_descriptor, NULL, thread_routine, this);
|
||||
posix_assert (rc);
|
||||
_started = true;
|
||||
@ -301,7 +342,8 @@ void zmq::thread_t::
|
||||
#endif
|
||||
}
|
||||
|
||||
void zmq::thread_t::setThreadName (const char *name_)
|
||||
void zmq::thread_t::
|
||||
applyThreadName () // to be called in secondary thread context
|
||||
{
|
||||
/* The thread name is a cosmetic string, added to ease debugging of
|
||||
* multi-threaded applications. It is not a big issue if this value
|
||||
@ -310,7 +352,7 @@ void zmq::thread_t::setThreadName (const char *name_)
|
||||
* "int rc" is retained where available, to help debuggers stepping
|
||||
* through code to see its value - but otherwise it is ignored.
|
||||
*/
|
||||
if (!name_)
|
||||
if (!_name[0])
|
||||
return;
|
||||
|
||||
/* Fails with permission denied on Android 5/6 */
|
||||
@ -319,19 +361,19 @@ void zmq::thread_t::setThreadName (const char *name_)
|
||||
#endif
|
||||
|
||||
#if defined(ZMQ_HAVE_PTHREAD_SETNAME_1)
|
||||
int rc = pthread_setname_np (name_);
|
||||
int rc = pthread_setname_np (_name);
|
||||
if (rc)
|
||||
return;
|
||||
#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_2)
|
||||
int rc = pthread_setname_np (pthread_self (), name_);
|
||||
int rc = pthread_setname_np (pthread_self (), _name);
|
||||
if (rc)
|
||||
return;
|
||||
#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_3)
|
||||
int rc = pthread_setname_np (pthread_self (), name_, NULL);
|
||||
int rc = pthread_setname_np (pthread_self (), _name, NULL);
|
||||
if (rc)
|
||||
return;
|
||||
#elif defined(ZMQ_HAVE_PTHREAD_SET_NAME)
|
||||
pthread_set_name_np (pthread_self (), name_);
|
||||
pthread_set_name_np (pthread_self (), _name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
@ -56,11 +56,11 @@ class thread_t
|
||||
inline thread_t () :
|
||||
_tfn (NULL),
|
||||
_arg (NULL),
|
||||
_name (""),
|
||||
_started (false),
|
||||
_thread_priority (ZMQ_THREAD_PRIORITY_DFLT),
|
||||
_thread_sched_policy (ZMQ_THREAD_SCHED_POLICY_DFLT)
|
||||
{
|
||||
memset (_name, 0, sizeof (_name));
|
||||
}
|
||||
|
||||
#ifdef ZMQ_HAVE_VXWORKS
|
||||
@ -74,6 +74,8 @@ class thread_t
|
||||
|
||||
// Creates OS thread. 'tfn' is main thread function. It'll be passed
|
||||
// 'arg' as an argument.
|
||||
// Name is 16 characters max including terminating NUL. Thread naming is
|
||||
// implemented only for pthread, and windows when a debugger is attached.
|
||||
void start (thread_fn *tfn_, void *arg_, const char *name_);
|
||||
|
||||
// Returns whether the thread was started, i.e. start was called.
|
||||
@ -92,16 +94,13 @@ class thread_t
|
||||
int scheduling_policy_,
|
||||
const std::set<int> &affinity_cpus_);
|
||||
|
||||
// Sets the thread name, 16 characters max including terminating NUL.
|
||||
// Only implemented for pthread. Has no effect on other platforms.
|
||||
void setThreadName (const char *name_);
|
||||
|
||||
// These are internal members. They should be private, however then
|
||||
// they would not be accessible from the main C routine of the thread.
|
||||
void applySchedulingParameters ();
|
||||
void applyThreadName ();
|
||||
thread_fn *_tfn;
|
||||
void *_arg;
|
||||
std::string _name;
|
||||
char _name[16];
|
||||
|
||||
private:
|
||||
bool _started;
|
||||
|
@ -95,3 +95,10 @@ static inline int poll (struct pollfd *pfd, unsigned long nfds, int timeout)
|
||||
#define AI_NUMERICSERV 0x0400
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// In MSVC prior to v14, snprintf is not available
|
||||
// The closest implementation is the _snprintf_s function
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf(buffer_, count_, format_, ...) \
|
||||
_snprintf_s (buffer_, count_, _TRUNCATE, format_, __VA_ARGS__)
|
||||
#endif
|
||||
|
@ -48,10 +48,6 @@
|
||||
|
||||
char error_message_buffer[256];
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
void *handler;
|
||||
void *zap_thread;
|
||||
void *server;
|
||||
|
@ -96,6 +96,13 @@ enum
|
||||
};
|
||||
#endif
|
||||
|
||||
// In MSVC prior to v14, snprintf is not available
|
||||
// The closest implementation is the _snprintf_s function
|
||||
#if defined _MSC_VER && _MSC_VER < 1900
|
||||
#define snprintf(buffer_, count_, format_, ...) \
|
||||
_snprintf_s (buffer_, count_, _TRUNCATE, format_, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define LIBZMQ_UNUSED(object) (void) object
|
||||
|
||||
// Bounce a message from client to server and back
|
||||
|
@ -35,10 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <unity.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// Internal helper functions that are not intended to be directly called from
|
||||
// tests. They must be declared in the header since they are used by macros.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user