Java directors - more generic thread name setting

Activated if a user sets SWIG_JAVA_USE_THREAD_NAME.
Implementations provided for linux/android/macos/unix.
A user's implementation will be used if SWIG_JAVA_GET_THREAD_NAME is
defined. It must implement the function:
  namespace Swig {
    SWIGINTERN int GetThreadName(char *name, size_t len);
  }
This commit is contained in:
William S Fulton 2018-10-08 21:29:11 +01:00
commit 3195c3e4da
3 changed files with 71 additions and 14 deletions

View file

@ -7,6 +7,11 @@
%module(directors="1") director_thread %module(directors="1") director_thread
#endif #endif
%begin %{
#define SWIG_JAVA_USE_THREAD_NAME
//#define DEBUG_DIRECTOR_THREAD_NAME
%}
%{ %{
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -89,10 +94,23 @@ extern "C" {
fprintf(stderr, "pthread_create failed in run()\n"); fprintf(stderr, "pthread_create failed in run()\n");
assert(0); assert(0);
} }
int setname = pthread_setname_np(thread, "MyThreadName");
if (setname != 0) {
fprintf(stderr, "pthread_setname_np failed in run()\n");
assert(0);
}
%#endif %#endif
MilliSecondSleep(500); MilliSecondSleep(500);
} }
static bool namedThread() {
%#ifdef _WIN32
return false;
%#else
return true;
%#endif
}
virtual void do_foo() { virtual void do_foo() {
val += 1; val += 1;
} }

View file

@ -30,6 +30,12 @@ class director_thread_Derived extends Foo {
} }
public void do_foo() { public void do_foo() {
// Not all operating systems can name threads, so only test on those that can
if (Foo.namedThread()) {
String threadName = Thread.currentThread().getName();
if (!threadName.equals("MyThreadName"))
throw new RuntimeException("Unexpected thread name: " + threadName);
}
setVal(getVal() - 1); setVal(getVal() - 1);
} }
} }

View file

@ -5,20 +5,52 @@
* methods can be called from C++. * methods can be called from C++.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
#if defined(__ANDROID__) #if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) || defined(DEBUG_DIRECTOR_THREAD_NAME)
#include <sys/prctl.h>
#endif
#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION)
#if defined(__ANDROID__)
#include <errno.h>
#include <string.h>
#endif
#include <iostream> #include <iostream>
#endif #endif
#include <exception> #include <exception>
#if defined(SWIG_JAVA_USE_THREAD_NAME)
#if !defined(SWIG_JAVA_GET_THREAD_NAME)
namespace Swig {
SWIGINTERN int GetThreadName(char *name, size_t len);
}
#if defined(__linux__)
#include <sys/prctl.h>
SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
(void)len;
#if defined(PR_GET_NAME)
return prctl(PR_GET_NAME, (unsigned long)name, 0, 0, 0);
#else
(void)name;
return 1;
#endif
}
#elif defined(__unix__)
#include <pthread.h>
SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
return pthread_getname_np(pthread_self(), name, len);
}
#else
SWIGINTERN int Swig::GetThreadName(char *name, size_t len) {
(void)len;
(void)name;
return 1;
}
#endif
#endif
#endif
namespace Swig { namespace Swig {
/* Java object wrapper */ /* Java object wrapper */
@ -151,13 +183,14 @@ namespace Swig {
args.version = JNI_VERSION_1_2; args.version = JNI_VERSION_1_2;
args.group = NULL; args.group = NULL;
args.name = NULL; args.name = NULL;
#if defined(__ANDROID__) #if defined(SWIG_JAVA_USE_THREAD_NAME)
char thread_name[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel. char thread_name[16]; // MAX_TASK_COMM_LEN=16 is hard-coded in the kernel.
if (prctl(PR_GET_NAME, (unsigned long)thread_name, 0, 0, 0) == 0) { if (Swig::GetThreadName(thread_name, sizeof(thread_name)) == 0) {
args.name = thread_name; args.name = thread_name;
#if defined(DEBUG_DIRECTOR_THREAD_NAME)
std::cout << "JNIEnvWrapper: thread name: " << thread_name << std::endl;
} else { } else {
#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) std::cout << "JNIEnvWrapper: Couldn't set Java thread name" << std::endl;
std::cerr << "JNIEnvWrapper: Couldn't set thread name: " << strerror(errno) << std::endl;
#endif #endif
} }
#endif #endif