mirror of
https://github.com/zeromq/libzmq.git
synced 2025-01-14 09:47:56 +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);
|
_thread_affinity_cpus);
|
||||||
|
|
||||||
char namebuf[16] = "";
|
char namebuf[16] = "";
|
||||||
#ifdef ZMQ_HAVE_WINDOWS
|
|
||||||
LIBZMQ_UNUSED (name_);
|
|
||||||
#else
|
|
||||||
snprintf (namebuf, sizeof (namebuf), "%s%sZMQbg%s%s",
|
snprintf (namebuf, sizeof (namebuf), "%s%sZMQbg%s%s",
|
||||||
_thread_name_prefix.empty () ? "" : _thread_name_prefix.c_str (),
|
_thread_name_prefix.empty () ? "" : _thread_name_prefix.c_str (),
|
||||||
_thread_name_prefix.empty () ? "" : "/", name_ ? "/" : "",
|
_thread_name_prefix.empty () ? "" : "/", name_ ? "/" : "",
|
||||||
name_ ? name_ : "");
|
name_ ? name_ : "");
|
||||||
#endif
|
|
||||||
thread_.start (tfn_, arg_, namebuf);
|
thread_.start (tfn_, arg_, namebuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,10 +57,8 @@ zmq::io_thread_t::~io_thread_t ()
|
|||||||
void zmq::io_thread_t::start ()
|
void zmq::io_thread_t::start ()
|
||||||
{
|
{
|
||||||
char name[16] = "";
|
char name[16] = "";
|
||||||
#ifndef ZMQ_HAVE_WINDOWS
|
|
||||||
snprintf (name, sizeof (name), "IO/%u",
|
snprintf (name, sizeof (name), "IO/%u",
|
||||||
get_tid () - zmq::ctx_t::reaper_tid - 1);
|
get_tid () - zmq::ctx_t::reaper_tid - 1);
|
||||||
#endif
|
|
||||||
// Start the underlying I/O thread.
|
// Start the underlying I/O thread.
|
||||||
_poller->start (name);
|
_poller->start (name);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ static unsigned int __stdcall thread_routine (void *arg_)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
||||||
|
self->applyThreadName ();
|
||||||
self->_tfn (self->_arg);
|
self->_tfn (self->_arg);
|
||||||
return 0;
|
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_)
|
void zmq::thread_t::start (thread_fn *tfn_, void *arg_, const char *name_)
|
||||||
{
|
{
|
||||||
LIBZMQ_UNUSED (name_);
|
|
||||||
_tfn = tfn_;
|
_tfn = tfn_;
|
||||||
_arg = arg_;
|
_arg = arg_;
|
||||||
|
if (name_)
|
||||||
|
strncpy (_name, name_, sizeof (_name));
|
||||||
#if defined _WIN32_WCE
|
#if defined _WIN32_WCE
|
||||||
_descriptor =
|
_descriptor =
|
||||||
(HANDLE) CreateThread (NULL, 0, &::thread_routine, this, 0, NULL);
|
(HANDLE) CreateThread (NULL, 0, &::thread_routine, this, 0, NULL);
|
||||||
@ -92,10 +94,48 @@ void zmq::thread_t::setSchedulingParameters (
|
|||||||
LIBZMQ_UNUSED (affinity_cpus_);
|
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
|
// 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
|
#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
|
// not implemented
|
||||||
LIBZMQ_UNUSED (name_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -181,7 +221,7 @@ static void *thread_routine (void *arg_)
|
|||||||
#endif
|
#endif
|
||||||
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
zmq::thread_t *self = (zmq::thread_t *) arg_;
|
||||||
self->applySchedulingParameters ();
|
self->applySchedulingParameters ();
|
||||||
self->setThreadName (self->_name.c_str ());
|
self->applyThreadName ();
|
||||||
self->_tfn (self->_arg);
|
self->_tfn (self->_arg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -191,7 +231,8 @@ void zmq::thread_t::start (thread_fn *tfn_, void *arg_, const char *name_)
|
|||||||
{
|
{
|
||||||
_tfn = tfn_;
|
_tfn = tfn_;
|
||||||
_arg = arg_;
|
_arg = arg_;
|
||||||
_name = name_;
|
if (name_)
|
||||||
|
strncpy (_name, name_, sizeof (_name));
|
||||||
int rc = pthread_create (&_descriptor, NULL, thread_routine, this);
|
int rc = pthread_create (&_descriptor, NULL, thread_routine, this);
|
||||||
posix_assert (rc);
|
posix_assert (rc);
|
||||||
_started = true;
|
_started = true;
|
||||||
@ -301,7 +342,8 @@ void zmq::thread_t::
|
|||||||
#endif
|
#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
|
/* The thread name is a cosmetic string, added to ease debugging of
|
||||||
* multi-threaded applications. It is not a big issue if this value
|
* 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
|
* "int rc" is retained where available, to help debuggers stepping
|
||||||
* through code to see its value - but otherwise it is ignored.
|
* through code to see its value - but otherwise it is ignored.
|
||||||
*/
|
*/
|
||||||
if (!name_)
|
if (!_name[0])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Fails with permission denied on Android 5/6 */
|
/* Fails with permission denied on Android 5/6 */
|
||||||
@ -319,19 +361,19 @@ void zmq::thread_t::setThreadName (const char *name_)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ZMQ_HAVE_PTHREAD_SETNAME_1)
|
#if defined(ZMQ_HAVE_PTHREAD_SETNAME_1)
|
||||||
int rc = pthread_setname_np (name_);
|
int rc = pthread_setname_np (_name);
|
||||||
if (rc)
|
if (rc)
|
||||||
return;
|
return;
|
||||||
#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_2)
|
#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)
|
if (rc)
|
||||||
return;
|
return;
|
||||||
#elif defined(ZMQ_HAVE_PTHREAD_SETNAME_3)
|
#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)
|
if (rc)
|
||||||
return;
|
return;
|
||||||
#elif defined(ZMQ_HAVE_PTHREAD_SET_NAME)
|
#elif defined(ZMQ_HAVE_PTHREAD_SET_NAME)
|
||||||
pthread_set_name_np (pthread_self (), name_);
|
pthread_set_name_np (pthread_self (), _name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <cstring>
|
||||||
|
|
||||||
namespace zmq
|
namespace zmq
|
||||||
{
|
{
|
||||||
@ -56,11 +56,11 @@ class thread_t
|
|||||||
inline thread_t () :
|
inline thread_t () :
|
||||||
_tfn (NULL),
|
_tfn (NULL),
|
||||||
_arg (NULL),
|
_arg (NULL),
|
||||||
_name (""),
|
|
||||||
_started (false),
|
_started (false),
|
||||||
_thread_priority (ZMQ_THREAD_PRIORITY_DFLT),
|
_thread_priority (ZMQ_THREAD_PRIORITY_DFLT),
|
||||||
_thread_sched_policy (ZMQ_THREAD_SCHED_POLICY_DFLT)
|
_thread_sched_policy (ZMQ_THREAD_SCHED_POLICY_DFLT)
|
||||||
{
|
{
|
||||||
|
memset (_name, 0, sizeof (_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZMQ_HAVE_VXWORKS
|
#ifdef ZMQ_HAVE_VXWORKS
|
||||||
@ -74,6 +74,8 @@ class thread_t
|
|||||||
|
|
||||||
// Creates OS thread. 'tfn' is main thread function. It'll be passed
|
// Creates OS thread. 'tfn' is main thread function. It'll be passed
|
||||||
// 'arg' as an argument.
|
// '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_);
|
void start (thread_fn *tfn_, void *arg_, const char *name_);
|
||||||
|
|
||||||
// Returns whether the thread was started, i.e. start was called.
|
// Returns whether the thread was started, i.e. start was called.
|
||||||
@ -92,16 +94,13 @@ class thread_t
|
|||||||
int scheduling_policy_,
|
int scheduling_policy_,
|
||||||
const std::set<int> &affinity_cpus_);
|
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
|
// These are internal members. They should be private, however then
|
||||||
// they would not be accessible from the main C routine of the thread.
|
// they would not be accessible from the main C routine of the thread.
|
||||||
void applySchedulingParameters ();
|
void applySchedulingParameters ();
|
||||||
|
void applyThreadName ();
|
||||||
thread_fn *_tfn;
|
thread_fn *_tfn;
|
||||||
void *_arg;
|
void *_arg;
|
||||||
std::string _name;
|
char _name[16];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _started;
|
bool _started;
|
||||||
|
@ -95,3 +95,10 @@ static inline int poll (struct pollfd *pfd, unsigned long nfds, int timeout)
|
|||||||
#define AI_NUMERICSERV 0x0400
|
#define AI_NUMERICSERV 0x0400
|
||||||
#endif
|
#endif
|
||||||
#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];
|
char error_message_buffer[256];
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *handler;
|
void *handler;
|
||||||
void *zap_thread;
|
void *zap_thread;
|
||||||
void *server;
|
void *server;
|
||||||
|
@ -96,6 +96,13 @@ enum
|
|||||||
};
|
};
|
||||||
#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
|
||||||
|
|
||||||
#define LIBZMQ_UNUSED(object) (void) object
|
#define LIBZMQ_UNUSED(object) (void) object
|
||||||
|
|
||||||
// Bounce a message from client to server and back
|
// 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>
|
#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
|
// 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.
|
// tests. They must be declared in the header since they are used by macros.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user