Is there any Debug logging I can enable in JNA

2,467 views
Skip to first unread message

declan

unread,
Jan 28, 2012, 9:19:38 AM1/28/12
to Java Native Access
Hi Guys

First post to JNA mailing group so I hope I have included all the
information required for you guys to be able tp help me.

OS: RHEL6.1 64bit Arch. x86_64 GNU/Linux
JNA Version:3.2.4
GStreamer-Java bindings version: 1.5
GStreamer Version: 0.10 (gstreamer-0.10.33)

I have recently started using GStreamer, with JAVA using the GStreamer-
Java bindings, which in turn uses JNA to handle moving between JAVA
and the Native code.

I have found this issue which Im trying to root cause and need some
assistance from JNA. Problem description: Under load testing I have
found that sometimes the callback from GStreamer native land takes a
very long time to complete in the range of 6-11 seconds to complete.
Normally this specific callback take less than second, its a callback
to invoke sinkRender from Gstreamer basicsink class. As I say 9.99
times out of 10 under load this delay doesnt occur but occasionally it
takes a long time causing other issues due to this delay.

So I have added diagnostics to the native code to log times before and
after callback is invoked, and see this delay occuring. I have also
added similar diagnostics to the GStreamer-Java code to log times when
it first enter its base class, CustomSink.java and
WriteableByteChannelSink.java. By the time the request has got to
GStreamer-Java code the long delay of between 6-11 seconds has already
occured.

So I need to determine if JNA is the bottleneck here or something else
entirely. The stack trace shown below shows the JNA methods invoked.
So my question is there any diagnostics I can enable (and how) that
might help in trying to root cause this issue.

If not I'm happy to add diagnostics myself into the source code and
build it. Can I build from eclipse? Are there an instructions on how
to build the source code from JNA.


Any help much appreciated. Let me know if I need to supply more
details.

Thanks
Declan

Stack Trace when Enter GStreamer-Java.

at
org.gstreamer.io.WriteableByteChannelSink.sinkRender(WriteableByteChannelSink.java:
72)
at org.gstreamer.elements.CustomSink
$1.callback(CustomSink.java:150)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.jna.CallbackReference
$DefaultCallbackProxy.invokeCallback(CallbackReference.java:384)
at com.sun.jna.CallbackReference
$DefaultCallbackProxy.callback(CallbackReference.java:414)

GStreeamer - Native callback
====================
gstreamer-0.10.33/libs/gst/base/gstbasesink.c line:3006 approximately

ret = bclass->render (basesink, buf);

Render function definition; gstreamer-0.10.33/libs/gst/base/
gstbasesink.h, line 168.
GstFlowReturn (*render) (GstBaseSink *sink, GstBuffer *buffer);

Timothy Wall

unread,
Jan 28, 2012, 1:09:09 PM1/28/12
to jna-...@googlegroups.com
Take a look at Native.setCallbackThreadInitializer(), which lets you specify behavior and settings around mapping native threads into Java Thread objects. You'll want to at least set things up to avoid detaching your native threads.

Might not be the only issue, but it's the most obvious operation that sits between the native callback invocation and execution of Java code.

T.

Neil C Smith

unread,
Jan 28, 2012, 2:39:00 PM1/28/12
to jna-...@googlegroups.com
Declan,

I saw your message on the GStreamer-Java list too. I use that library
quite a bit myself. As a follow on to Timothy's reply, I wondered if
you'd tried using VisualVM and looking to see if anything spikes when
you see this problem? I found this useful when I reported the thread
detach issue because there were obvious garbage collection spikes
happening. Whether GC could be the cause of your pause I don't know
though, as it seems rather long.

It might be easier to use Native.detach(false) to check if thread
detachment is an issue. Using a callback thread initializer is a bit
awkward with GStreamer-Java as the JNA callback can be buried quite
deep.

You'll need a newer JNA (3.4.0) than you're using too.

Best wishes,

Neil

--
Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

declan harrison

unread,
Jan 29, 2012, 7:05:17 AM1/29/12
to jna-...@googlegroups.com
> Take a look at Native.setCallbackThreadInitializer(), which lets you specify behavior and settings around mapping native threads into Java Thread objects.  You'll want to at least set things up to avoid detaching your native threads.
>
> Might not be the only issue, but it's the most obvious operation that sits between the native callback invocation and execution of Java code.
>
> T.
>
Tim

Thanks for the lead I will follow up today. Will provide update when I
make changes

Declan

declan harrison

unread,
Jan 29, 2012, 7:13:54 AM1/29/12
to jna-...@googlegroups.com
Neil

Thanks for feedback, I have some comments inline.

Declan


> I saw your message on the GStreamer-Java list too.  I use that library
> quite a bit myself.  As a follow on to Timothy's reply, I wondered if
> you'd tried using VisualVM and looking to see if anything spikes when
> you see this problem?  I found this useful when I reported the thread
> detach issue because there were obvious garbage collection spikes
> happening.  Whether GC could be the cause of your pause I don't know
> though, as it seems rather long.
>

Neil, can you provide your perspective on the previous issue you
mentioned with the thread detach issue.

> It might be easier to use Native.detach(false) to check if thread
> detachment is an issue.  Using a callback thread initializer is a bit
> awkward with GStreamer-Java as the JNA callback can be buried quite
> deep.
>

Will try this first as suggested. Thanks


> You'll need a newer JNA (3.4.0) than you're using too.

Yea I have downloaded and sync the master version from github

Neil C Smith

unread,
Jan 29, 2012, 9:46:15 AM1/29/12
to jna-...@googlegroups.com
Hi Declan,

Quick response as I'm going to be away and offline for a couple of days.

If you want all the long and gory details, check out this thread -
https://groups.google.com/d/topic/jna-users/bxd-yf2Al9g/discussion

I've noticed a lot more GC in GStreamer-Java when not using thread
detach management, but nothing that causes problems anywhere near as
badly as you're seeing. It's not like GStreamer is doing 500
callbacks a second, which was my problem in JNAJack.

The other thing I'd look for is if your code or the GStreamer-Java
code you're using is allocating lots of Java memory per callback
rather than caching and reusing.

Good luck with it!

Best wishes,

Neil

--

declan harrison

unread,
Jan 29, 2012, 11:58:54 AM1/29/12
to jna-...@googlegroups.com
Hi

Checking the JavaDoc for method, Native.detach(boolean), says the
following "Warning: avoid calling {@link #detach detach(true)} on a VM
thread;
the resulting behavior is not defined.<p/>"

How and where should this be invoked if not from my Java Application
layer, or does the GStreamer-Java library need to do this. I had
assumed that I would call this from my Java application each time I
create a gstreamer pipeline but I don't see this working. I suspect
it must be done when GStreamer-Java library when it registers all its
callback.

Apologies if these questions are very basic, I'm not familiar with
the detail of JNA development but I'm keen to learn

Thanks
Declan

Timothy Wall

unread,
Jan 29, 2012, 12:46:41 PM1/29/12
to jna-...@googlegroups.com
* You have threads originating from the VM (either the initial thread or subsequent threads spawned from Java code with Thread.start()).

* You have threads spawned from native code (dependent on whatever native libraries you're using). These native threads are temporarily mapped to a Java Thread object if a JNA callback is invoked.

Native.detach(false) should only be called when you're on one of the latter types of threads.

declan

unread,
Feb 2, 2012, 12:11:11 PM2/2/12
to Java Native Access
Hi Tim/Neil

Just wanted to provide you guys with an update after some exhaustive
testing by myself and QE team.

Following your suggestions I added the call "Native.detach(false)" on
the callback thread (native thread) in Java for 2 GStreamer-Java
related I/O classes (use one for Reading and one for Writing). The
change has worked really well for me. The effect of this has meant
that I no longer get the time-out on the write which was happening a
lot under load; many thanks.

I have some further questions about using this call
"Native.detach(false)". So the I/O callbacks in gstreamer-java happen
a lot during the lifetime of each request, many read callbacks for
chunks and many write callbacks to read/write chunk of data. So
depending how large the input video content file is we can invoke
these callbacks many hundred of times for one request and you can
scale this up under load.

So if I always call "Native.detach(false)" on the callback thread
does this mean that this thread will never detach and therefore will
never be destroyed in Java land? Downside is that these threads would
continually grow under load if that assumption is correct?

If this is true, then for I/O related callbacks would it be best to
only call "Native.detach(false)" when the I/O was successful? For
example if a read hits EOF then it should NOT call
"Native.detach(false)".

As I said the change recommended have worked really well for me, just
need some clarity on the effect of this change has as I have
subsequently seen a number of threads in JAVA in a "Runnable" state
but no back stacktrace, when I do a jstack.

Thanks
Declan

Timothy Wall

unread,
Feb 3, 2012, 5:44:50 PM2/3/12
to jna-...@googlegroups.com
See comments below

Threads are normally detached when they are unattached on entry, so if you want to force a detach (presumably on a thread on which you previously called Native.detach(false)), you must call Native.detach(true);

You want to watch out for a scenario where the native thread dies without first calling a callback in which you can determine that it's time to detach.


>
> As I said the change recommended have worked really well for me, just
> need some clarity on the effect of this change has as I have
> subsequently seen a number of threads in JAVA in a "Runnable" state
> but no back stacktrace, when I do a jstack.

This would be attached native threads from which your Java callback has returned. I doubt the VM is set up to automatically detect thread death if the VM didn't spawn it (which would be required in order to automatically GC finished threads).


>
> Thanks
> Declan

declan

unread,
Feb 6, 2012, 4:22:48 PM2/6/12
to Java Native Access
Hi Tim

The two points you make below are I believe the exact use case I am
seeing under certain circumstances. Basically when everything goes as
expected I can determine when to call Native.detach(true) (having
previously called Native.detach(false)) on a callback thread and thus
ensuring callback thread is detached. However if there's an I/O error
on the stream then either one of the read or write callbacks is never
invoked again and therefore I never get the chance to detach the
thread that I would now like to detach, this mean its always show in
the jstack as this, note the "0x0000000000000000".

"Thread-12964" prio=10 tid=0x00007f3c52fe7000 nid=0x2193d runnable
[0x0000000000000000]
java.lang.Thread.State: RUNNABLE


> You want to watch out for a scenario where the native thread dies without first calling a callback in which you can determine that it's time to detach.

> This would be attached native threads from which your Java callback has returned.  I doubt the VM is set up to automatically detect thread death if the VM didn't spawn it (which would be required in order to automatically GC finished threads).

Based on what you state above, Is there a way to remove these attached
native threads automatically? Is there a way to have JNA invoke this
callback thread so that it can be detached? Or is there a recommended
approach for this type of use case which I suspect is a fairly
standard approach.

Thanks
Declan

Neil C Smith

unread,
Feb 6, 2012, 5:00:39 PM2/6/12
to jna-...@googlegroups.com
Hi Tim / Declan,

Might be worth revisiting the conversation about thread-local
destructors, such as mentioned here -
https://groups.google.com/d/msg/jna-users/bxd-yf2Al9g/h34MsCnW7CcJ

The infrastructure now in JNA should make it possible to create a
utility for this without any further changes to JNA itself. I may be
able to help out with this if needed as I'm in the same situation with
JNAJack (at the moment I'm not seeing any adverse affects, but I'd
rather not have the dead Thread objects hanging around).

Best wishes,

Neil

--

declan

unread,
Feb 7, 2012, 5:27:35 AM2/7/12
to Java Native Access
Hi Neil

I presume your talking about changes in native code to facilitate
this? I take it there's not much we can do in Java when this happens
if the callback is never invoked again as the thread is effectively
owned by the native code.

This utility would run as a separate thread when JNA is loaded? Let
me know in more detail your thoughts here and we can work together to
provide a good solution to this issue as I think its a use case a lot
of developers will need to address if not detaching the thread. In my
case it around I/O callbacks but could equally apply to other
callbacks.

Declan

declan

unread,
Feb 7, 2012, 6:06:33 AM2/7/12
to Java Native Access

>
> Might be worth revisiting the conversation about thread-local
> destructors, such as mentioned here -https://groups.google.com/d/msg/jna-users/bxd-yf2Al9g/h34MsCnW7CcJ
>

Hi Neil

Re-read this email thread again. Yea I see the feature you guys
discussed which is this actual use case I have. Its called out in the
email thread as " add thread termination handler to non-detached
threads" and suggested "ways to do this: o additional interface
"CallbackNoDetach", "CallbackAsDaemon".

However I think in the end it was decided not to implement this but to
leave it until a requirement was needed in a real world use case. So
are you thinking of having a callback in JNA to handle the case when
thread is destroyed or something outside of JNA? It seems to me that
having the ability to do both is ideal if JNA provided some hooks it
would be good I think.

Let me know your thoughts

Declan

Timothy Wall

unread,
Feb 7, 2012, 8:03:37 AM2/7/12
to jna-...@googlegroups.com

On Feb 7, 2012, at 6:06 AM, declan wrote:

>
>>
>> Might be worth revisiting the conversation about thread-local
>> destructors, such as mentioned here -https://groups.google.com/d/msg/jna-users/bxd-yf2Al9g/h34MsCnW7CcJ
>>
>
> Hi Neil
>
> Re-read this email thread again. Yea I see the feature you guys
> discussed which is this actual use case I have. Its called out in the
> email thread as " add thread termination handler to non-detached
> threads" and suggested "ways to do this: o additional interface
> "CallbackNoDetach", "CallbackAsDaemon".

Well, internally it'd be something that JNA does when you call Native.detach(false). pthreads has a mechanism for registering a callback when a thread is about to be destroyed, so JNA could use JNA to register such a callback (with an equivalent on w32) and handle all bookkeeping, without requiring any changes on the native side.

>
> However I think in the end it was decided not to implement this but to
> leave it until a requirement was needed in a real world use case. So
> are you thinking of having a callback in JNA to handle the case when
> thread is destroyed or something outside of JNA? It seems to me that
> having the ability to do both is ideal if JNA provided some hooks it
> would be good I think.
>
> Let me know your thoughts

You can actually implement this outside of JNA to isolate the proper behavior, and then we can figure out where best to have JNA handle it automagically. Prior to calling Native.detach(false) (i.e. identifying a new thread that you want to "keep around"), you set up the pthread callbacks. For the moment, the only thing the destroy callback needs to do is call Native.detach(true) before returning, but you may come up with other things (like perhaps a hook to client code for native thread destroy notification, which might be nice for cleaning up any memory which might have been allocated for that thread's use).

Timothy Wall

unread,
Feb 7, 2012, 3:00:20 PM2/7/12
to jna-...@googlegroups.com
BTW, this seems to be the preferred method of detecting a win32 thread exit:

DWORD result = WaitForSingleObject(hThread, 0);
if (result == WAIT_OBJECT_0) {
// thread has terminated
}
else {
// thread still alive
}

So you'd need a dedicated thread to watch the native thread...this could probably be adapted to watch for multiples, though, so you'd only need one monitoring thread on win32.

On Feb 7, 2012, at 6:06 AM, declan wrote:

Neil C Smith

unread,
Feb 7, 2012, 3:54:45 PM2/7/12
to jna-...@googlegroups.com
> On Feb 7, 2012, at 6:06 AM, declan wrote:
>
> However I think in the end it was decided not to implement this but to
> leave it until a requirement was needed in a real world use case.

That's not exactly my recollection / perspective on it, as I've always
had a real-world use case in mind. However, the only change that had
to be made *in* JNA to facilitate this was the detach stuff. The rest
can hopefully be built *with* JNA (not that eventually having
something in the core library eventually wouldn't be a big plus).

On 7 February 2012 20:00, Timothy Wall <twal...@java.net> wrote:
> BTW, this seems to be the preferred method of detecting a win32 thread exit:
>
> DWORD result = WaitForSingleObject(hThread, 0);
> if (result == WAIT_OBJECT_0) {
>        // thread has terminated
> }
> else {
>        // thread still alive
> }
>
> So you'd need a dedicated thread to watch the native thread...this could probably be adapted to watch for multiples, though, so you'd only need one monitoring thread on win32.
>

Is that the mechanism Boost uses? Not in a position to look through
that code for a few days as I'm travelling. I know that the Boost
library provides thread destructors across Windows and pthreads
though.

N

declan

unread,
Feb 7, 2012, 5:57:12 PM2/7/12
to Java Native Access


On Feb 7, 8:54 pm, Neil C Smith <n...@neilcsmith.net> wrote:
> > On Feb 7, 2012, at 6:06 AM, declan wrote:
>
> > However I think in the end it was decided not to implement this but to
> > leave it until a requirement was needed in a real world use case.
>
> That's not exactly my recollection / perspective on it, as I've always
> had a real-world use case in mind.  However, the only change that had
> to be made *in* JNA to facilitate this was the detach stuff.  The rest
> can hopefully be built *with* JNA (not that eventually having
> something in the core library eventually wouldn't be a big plus).
>
> On 7 February 2012 20:00, Timothy Wall <twallj...@java.net> wrote:
>
> > BTW, this seems to be the preferred method of detecting a win32 thread exit:
>
> > DWORD result = WaitForSingleObject(hThread, 0);
> > if (result == WAIT_OBJECT_0) {
> >        // thread has terminated
> > }
> > else {
> >        // thread still alive
> > }
>
> > So you'd need a dedicated thread to watch the native thread...this could probably be adapted to watch for multiples, though, so you'd only need one monitoring thread on win32.
>
> Is that the mechanism Boost uses?  Not in a position to look through
> that code for a few days as I'm travelling.  I know that the Boost
> library provides thread destructors across Windows and pthreads
> though.

Hi Guys

I was planning to do something on the native side based on this
article http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier/,
which was referenced in the original email thread.

Is this the best approach to take here? I don't have much JNI/JNA
experience, so any tips welcome. Also my assumption is that all of
this processing must be done in native side as there are no available
hooks at present in Java to invoke when this native thread terminates.


Thanks
Declan

Timothy Wall

unread,
Feb 7, 2012, 7:52:09 PM2/7/12
to jna-...@googlegroups.com

On Feb 7, 2012, at 5:57 PM, declan wrote:

>
> Hi Guys
>
> I was planning to do something on the native side based on this
> article http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier/,
> which was referenced in the original email thread.
>

That link is roughly equivalent to what JNA already takes care of (via Native.detach()); it already handles automatically attaching native threads for Java callbacks. I was under the impression that boost has some sort of implementation for thread termination listeners; hopefully this is not just an attachment to a boost class object destructor.


> Is this the best approach to take here? I don't have much JNI/JNA
> experience, so any tips welcome. Also my assumption is that all of
> this processing must be done in native side as there are no available
> hooks at present in Java to invoke when this native thread terminates.

What needs to be done is hook up listeners for thread termination (using JNA mappings onto libpthread or kernel32). Boost apparently has these hooks in place so it should be straightforward to mimic the operations.

I do know that pthreads provides at least pthread_join and pthread_cleanup_push (the latter is probably more useful). The general idea is something like this:

on Native.detach(false) (eventually performed by JNA automatically, but ok for client to do it before calling Native.detach for now)
if thread not tracked, track it and add a termination callback handler

in termination callback handler:
optionally call a client-supplied cleanup handler
call Native.detach(true);

The thread termination handler ensures JNA gets one final callback before the thread exits.

Neil C Smith

unread,
Feb 8, 2012, 9:44:23 AM2/8/12
to jna-...@googlegroups.com
Hi,

On 8 February 2012 00:52, Timothy Wall <twal...@java.net> wrote:
>
> On Feb 7, 2012, at 5:57 PM, declan wrote:
>
>>
>> Hi Guys
>>
>> I was planning to do something on the native side based on this
>> article http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier/,
>> which was referenced in the original email thread.
>>
>
> That link is roughly equivalent to what JNA already takes care of (via Native.detach()); it already handles automatically attaching native threads for Java callbacks.  I was under the impression that boost has some sort of implementation for thread termination listeners; hopefully this is not just an attachment to a boost class object destructor.
>
>

That link is meant to do automatic detachment at thread death using
boost::thread_specific_ptr. Not sure how easy that method would be to
use through JNA though, or what mechanism is going on under the hood.


>> Is this the best approach to take here? I don't have much JNI/JNA
>> experience, so any tips welcome. Also my assumption is that all of
>> this processing must be done in native side as there are no available
>> hooks at present in Java to invoke when this native thread terminates.
>
> What needs to be done is hook up listeners for thread termination (using JNA mappings onto libpthread or kernel32).  Boost apparently has these hooks in place so it should be straightforward to mimic the operations.
>
> I do know that pthreads provides at least pthread_join and pthread_cleanup_push (the latter is probably more useful).  The general idea is something like this:
>
> on Native.detach(false) (eventually performed by JNA automatically, but ok for client to do it before calling Native.detach for now)
>  if thread not tracked, track it and add a termination callback handler
>
> in termination callback handler:
>  optionally call a client-supplied cleanup handler
>  call Native.detach(true);
>
> The thread termination handler ensures JNA gets one final callback before the thread exits.

From recollection (our previous conversation on this was a while ago
now!) the way to achieve this with pthreads is pthread_key_create and
pthread_setspecific. That's the method in the other (Android) link
from the earlier thread, but I've also seen it elsewhere. I'm not
sure off-hand, but think that's how Boost handles thread termination
callbacks for pthreads. I think there's something similar for Windows
too.

I recall reading of problems with using pthread_cleanup_push for this.
Just need to see if I can find the links again!

Best wishes,

Neil

declan

unread,
Feb 9, 2012, 12:51:10 PM2/9/12
to Java Native Access
Hi,

So I have put together a protoyype of what I thought was a potential
solution to this using pthreads, utilizing pthread_key_create, ability
to have a callback destructor invoked when the thread is about to be
destroyed.

Detailed below is overview of the implementation. I can provide, file
and diff if required.

However thus far the results have been disappointing in that I still
see these dead threads hanging about in JVM, jstack shows them.
"Thread-1642" prio=10 tid=0x00007f7745b3c000 nid=0x50feb runnable
[0x0000000000000000]
java.lang.Thread.State: RUNNABLE


I cannot find the equivalent, thread on the pstack for the JVM, so
this has me concerned that Im missing something in the logic of my
prototype. Can you guys review and point out any gaps in the
prototype especially in relation to how JNA it handles its thread
management. Or this there an issue with thread pooling in gstreamer
here?

Im continuing to investigate but wanted to give you a heads up on
where I am here. This prototype is just that and the code has been
hacked together to see if it works.

Look forward to hearing from you.

Declan

All code changes is in callback.c.

I use pthread_once to create the thread specific in method
callback_dispatch e.g. pthread_once(&mylib_once_var,mylib_init). This
ensures that we create the key once only in the method mylib_init,
regardless how many times its called in code. This creates the key
and sets the thread callback, which is called when the thread is about
to terminate.

The only other change is after the callback_invoke is run if the errno
is set THREAD_LEAVE_ATTACHED, then I create Thread Specific Data (TSD)
and add the pointer to "JavaVM" to this data. If the errno is
THREAD_DETACH, then we set the TSD to indicate that this thread is
already detached. This continues until the thread is terminated and
the callback is invoked to detach the thread if it hasn't been
previously detached.

Im still seeing the problem in my test cases.

The code changes I have made has a lot of debug logging I have put in
to help me trace through the calls. The changes I have made are not
what would go into the finished JNA layer they are more to prove that
this works for us as expected.

Declan


26,30d25
< /* add pthread specific data */
< #include <pthread.h>
< #include <stdio.h>
< #include <stdlib.h>
< #include <unistd.h>
38,104d32
< /*
< * functions required for pthread thread local data
< *
< */
< void dataDestructor(void *data);
< void mylib_init();
<
< #define checkResults(string, val) { \
< if (val) { \
< printf("Failed with %d at %s", val, string); \
< exit(1); \
< } \
< }
<
< typedef struct {
< int detach;
< JavaVM* jvm;
< } threadSpecific_data_t;
<
< static pthread_key_t threadSpecificKey;
< pthread_once_t mylib_once_var=PTHREAD_ONCE_INIT;
<
< /*
< *
< * This function will be invoked once and once only by virtue
pthread_once
< * This will create the key that willbe used by all threads.
< *
< */
< void mylib_init()
< {
< int rc=0;
< rc = pthread_key_create(&threadSpecificKey, dataDestructor);
< fprintf(stdout, "Entering mylib_init TLS constructor :pthread_once
rc[%d] tid [%ld] \n",rc, pthread_self());
< fflush(stdout);
< checkResults("pthread_key_create()\n", rc);
< } /* mylib_init() */
<
< /*
< *
< * This destructor is invoked each time a thread is about to die
< * and we need to remove thread local storage.
< * Use this to detach the thread from the JVM if its attached.
< *
< */
< void dataDestructor(void *parm) {
< //printf("Thread %.8x %.8x: Free data\n",
pthread_getthreadid_np());
< threadSpecific_data_t *gData;
< gData = (threadSpecific_data_t *)parm;
< fprintf(stdout, "Entering Thread destructor: tid [%ld]
threadSpecific data=%d \n", pthread_self(), gData->detach);
< fflush(stdout);
< if (gData != NULL && gData->detach) {
< JavaVM* jvm = gData->jvm;
< fprintf(stdout, "Destructor Thread tid [%ld] TLS [%p] jvm
[%p]: still attached. detach the thread from the JVM, threadSpecific
data=%d \n",
< pthread_self(),gData,gData->jvm, gData-
>detach);
< fflush(stdout);
< if (jvm != NULL) {
< (*jvm)->DetachCurrentThread(jvm);
< fprintf(stdout, "Thread destructor tid [%ld]: have just
called DetachCurrentThread TLS [%p] jvm [%p]
\n",pthread_self(),gData,gData->jvm);
< fflush(stdout);
< }
< }
< pthread_setspecific(threadSpecificKey, NULL);
< free(parm);
< parm = NULL;
< }
<
<
139,141d66
< /* dharriso */
< fprintf(stdout, "create_callback tid [%ld]: called for callback
addr [%p] jvm addr [%p]\n", pthread_self(),cb,cb->vm);
< fflush(stdout);
273,275d197
< /* dharriso */
< fprintf(stdout, "free_callback tid [%ld]: called for callback addr
[%p] jvm addr [%p]\n",pthread_self(),cb,cb->vm);
< fflush(stdout);
328,329d249
< fprintf(stdout, "callback_invoke tid [%ld] \n",pthread_self());
< fflush(stdout);
482,484d401
< /* create the TLS key once and once only...use pthread_once */
< pthread_once(&mylib_once_var,mylib_init);
<
525,526d441
< fprintf(stdout, "callback_dispatch: called tid[%ld]: callback
addr [%p] jvm addr [%p]\n",pthread_self(),cb,cb->vm);
< fflush(stdout);
532,574c447,448
< case THREAD_LEAVE_ATTACHED:
< {
< /* dharriso */
< /* pthreads for thread detachement */
< /* if we have TLS use it otherwise create it and then use
it */
< threadSpecific_data_t *gData =
pthread_getspecific(threadSpecificKey);
< detach = JNI_FALSE;
< if (gData == NULL) {
< int rc = -1;
< /* we need to create this data and store it in thread
local. */
< gData = (threadSpecific_data_t
*)malloc(sizeof(threadSpecific_data_t));
< gData->detach = 1;
< gData->jvm = jvm;
< rc = pthread_setspecific(threadSpecificKey, gData);
< fprintf(stdout, "callback_dispatch: Thread left attached
tid[%ld]: TLS WAS created [%p], for callback addr [%p] jvm addr [%p]
\n",pthread_self(),gData,cb,cb->vm);
< fflush(stdout);
< checkResults("pthread_setspecific()\n", rc);
< } else {
< /* update this value to indicate that we need to detach
this thread */
< /* if this thread dies */
< fprintf(stdout, "callback_dispatch: Thread left attached
tid[%ld]: TLS ALREADY been created [%p], for callback addr [%p] jvm
addr [%p]\n",pthread_self(),gData,cb,cb->vm);
< fflush(stdout);
< gData->detach = 1;
< }
< }
< break;
< case THREAD_DETACH:
< {
< threadSpecific_data_t *gData =
pthread_getspecific(threadSpecificKey);
< detach = JNI_TRUE;
< /* only use TLS if its available */
< if (gData != NULL) {
< /* we have already detached dont need to doit
again */
< gData->detach = 0;
< fprintf(stdout, "callback_dispatch: Thread
detached but was previously attached tid[%ld]: TLS ALREADY created
[%p], for callback addr [%p] jvm addr [%p]
\n",pthread_self(),gData,cb,cb->vm);
< fflush(stdout);
< } else {
< fprintf(stdout, "callback_dispatch: Thread
detached and was NEVER left attached tid[%ld]: callback addr [%p] jvm
addr [%p]\n",
< pthread_self(),cb,cb->vm);
< fflush(stdout);
< }
< }
< break;
---
> case THREAD_LEAVE_ATTACHED: detach = JNI_FALSE; break;
> case THREAD_DETACH: detach = JNI_TRUE; break;
580d453
< /* are we detaching the thread now */
583c456
< }
---
> }


Neil C Smith

unread,
Feb 9, 2012, 2:37:08 PM2/9/12
to jna-...@googlegroups.com

Why not use JNA to wrap pthreads? As far as I remember all the necessary changes are in callback.c that would allow this to be done without making any further changes to JNA's native code.

N

--
Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

(sent while mobile through GoogleMail)

declan

unread,
Feb 9, 2012, 3:36:54 PM2/9/12
to Java Native Access


On Feb 9, 7:37 pm, Neil C Smith <n...@neilcsmith.net> wrote:
> Why not use JNA to wrap pthreads? As far as I remember all the necessary
> changes are in callback.c that would allow this to be done without making
> any further changes to JNA's native code.

Dont I need to make changes here in the native code to register a
callback for when the the thread terminates. Where else can this be
done from? I dont see any sipport this in the currently callback.c

Are you suggesting that this can be done purely from the Java side?
How do I register a callback that works such that when the native
thread terminates it invokes a Java callback? I dont see support for
this in the API?

Have I missed something in the code/logic here?

Thanks
Declan

Timothy Wall

unread,
Feb 9, 2012, 3:51:09 PM2/9/12
to jna-...@googlegroups.com

take a step back and think about it.

* you want to call a native function where one of the arguments is a function pointer

You callback (function pointer) is in Java. You only need to call Native.detach(true) before the thread termination callback returns; the existing JNA callback handling code (native) already does what's required to clean up the thread.

It might get messy if the callback is not called from the terminating thread, but I don't think that's going to be the case.

declan

unread,
Feb 9, 2012, 4:22:52 PM2/9/12
to Java Native Access
Tim/Neil

Sorry about this, Seems I have misread the changes required for JNA to
enable this to work, doh.

So I should use JNA as it is to register listeners for the pthread
commands in relation thread specific data and the termination of the
thread. Once I have these listeners in place then once the thread
termination callback is invoked we call Native.detach(true) so the
thread always detaches.

Ok, I get this now, doh. All new to me this, do I need to support all
the calls for pthreads, or just some. Any reference code worth
looking at here?

Declan

Timothy Wall

unread,
Feb 9, 2012, 4:52:02 PM2/9/12
to jna-...@googlegroups.com

On Feb 9, 2012, at 4:22 PM, declan wrote:

>
> Sorry about this, Seems I have misread the changes required for JNA to
> enable this to work, doh.
>
> So I should use JNA as it is to register listeners for the pthread
> commands in relation thread specific data and the termination of the
> thread. Once I have these listeners in place then once the thread
> termination callback is invoked we call Native.detach(true) so the
> thread always detaches.

Right. and once you get it working, we splice it into the Java side of JNA's Native.detach(true) so that it happens automagically.

>
> Ok, I get this now, doh. All new to me this, do I need to support all
> the calls for pthreads, or just some. Any reference code worth
> looking at here?

You only need to map the stuff you actually use.

Reply all
Reply to author
Forward
0 new messages