From 3195c3e4dac605aaa9ee877ea956151bc3e15830 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 8 Oct 2018 21:29:11 +0100 Subject: [PATCH] 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); } --- Examples/test-suite/director_thread.i | 20 ++++++- .../java/director_thread_runme.java | 6 ++ Lib/java/director.swg | 59 +++++++++++++++---- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/Examples/test-suite/director_thread.i b/Examples/test-suite/director_thread.i index 260bce774..cb999ecc4 100644 --- a/Examples/test-suite/director_thread.i +++ b/Examples/test-suite/director_thread.i @@ -7,6 +7,11 @@ %module(directors="1") director_thread #endif +%begin %{ +#define SWIG_JAVA_USE_THREAD_NAME +//#define DEBUG_DIRECTOR_THREAD_NAME +%} + %{ #ifdef _WIN32 #include @@ -89,10 +94,23 @@ extern "C" { fprintf(stderr, "pthread_create failed in run()\n"); assert(0); } + int setname = pthread_setname_np(thread, "MyThreadName"); + if (setname != 0) { + fprintf(stderr, "pthread_setname_np failed in run()\n"); + assert(0); + } %#endif MilliSecondSleep(500); } - + + static bool namedThread() { +%#ifdef _WIN32 + return false; +%#else + return true; +%#endif + } + virtual void do_foo() { val += 1; } diff --git a/Examples/test-suite/java/director_thread_runme.java b/Examples/test-suite/java/director_thread_runme.java index c67d4104f..9bc4a93b5 100644 --- a/Examples/test-suite/java/director_thread_runme.java +++ b/Examples/test-suite/java/director_thread_runme.java @@ -30,6 +30,12 @@ class director_thread_Derived extends 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); } } diff --git a/Lib/java/director.swg b/Lib/java/director.swg index ba06f9e0a..d4c88d5c6 100644 --- a/Lib/java/director.swg +++ b/Lib/java/director.swg @@ -5,20 +5,52 @@ * methods can be called from C++. * ----------------------------------------------------------------------------- */ -#if defined(__ANDROID__) -#include -#endif - -#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) -#if defined(__ANDROID__) -#include -#include -#endif +#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) || defined(DEBUG_DIRECTOR_THREAD_NAME) #include #endif #include +#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 +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 +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 { /* Java object wrapper */ @@ -151,13 +183,14 @@ namespace Swig { args.version = JNI_VERSION_1_2; args.group = 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. - 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; +#if defined(DEBUG_DIRECTOR_THREAD_NAME) + std::cout << "JNIEnvWrapper: thread name: " << thread_name << std::endl; } else { -#if defined(DEBUG_DIRECTOR_OWNED) || defined(DEBUG_DIRECTOR_EXCEPTION) - std::cerr << "JNIEnvWrapper: Couldn't set thread name: " << strerror(errno) << std::endl; + std::cout << "JNIEnvWrapper: Couldn't set Java thread name" << std::endl; #endif } #endif