Detecting thread interruption with JNA native wait call (Windows) - java

I'm trying to write some code that performs a wait via JNA (e.g. by calling the Kernel32 function WaitForSingleObject), but I'd also like the wait to finish if Thread.interrupt() is called; I assume Java uses something like an Event object to implement interruption; is there any way of getting the Event from Java in order to use it in a call to WaitForMultipleObjects? Or is there any other way I could arrange for my wait to finish if the thread is interrupted?

Java supports it via NIO and very few people are aware of, the class in question is abstract but that's no issue:
java.nio.channels.spi.AbstractInterruptibleChannel. It has 3 methods of interest: begin() and end(), those are final, plus that one you have to implement: "protected abstract void implCloseChannel() throws IOException"
The method is going to be called from the thread invoking interrupt(), so be careful.
The use is very simple: call begin before entering the native code and end() upon return. Handling the interruption in implCloseChannel.
Happy coding!

Having found a bit of time to do some more research, I went for a digging expedition in the OpenJDK source code this morning. It turns out that starting with the native implementation was wrong; there's a pure-Java mechanism for doing this.
The class sun.misc.SharedSecrets has a static method getJavaLangAccess(), which returns an object with a method blockedOn(Thread, sun.nio.ch.Interruptible). This can be used to arrange for Thread.interrupt() to call a method supplied by one of my own objects, at which point I can create my own interruption Event object with which I can ensure waits are terminated as required.
Doing this introduces dependencies on sun's implementation of the Java class library, but probably less so than digging through the JVM's native state to try to extract an event handle that it uses internally.

Related

How to have Process spawned by ProcessBuilder run a callback on completion/termination?

I'm writing a separate thread to monitor an OS process spawned by Java's ProcessBuilder. The process can sometimes get out of control. After a given timeout period, I want to kill the process if it's still running. I can paste my code in if it's helpful (please ask), but the only detail directly relevant to the question is that I'm using Process::waitFor to specify the timeout after which the process will be killed.
The problem is that this code design is relatively inefficient. As even the documentation for Process::waitFor says,
The default implementation of this methods polls the {#code exitValue}
to check if the process has terminated. Concrete implementations of this
class are strongly encouraged to override this method with a more
efficient implementation.
I'm thinking a much more efficient design would be to specify a callback to be executed after the process completes. I could execute my own timeout method that would kill the process if it were still running. But the callback, if run, would cancel the timeout kill method.
Can I implement a callback pattern for a process spawned by ProcessBuilder?
I'm looking at the ProcessBuilder.start(Redirect[] redirects) and wondering if I could just tack the execution of the callback at the end of this method. Problem is that the class is final, so I can't subclass it. I'd have to copy and modify. But I'd also have to duplicate such dependencies as ProcessEnvironment and ProcessImpl, which are not public, as well as being final. Ugh.
Is maybe there some way to extend the abstract class Process to use a callback? That class seems to have/be the only space left by the authors of Java for fixing up the inefficient code they've left.
Or perhaps there's another way to make Process::waitFor more efficient?

SIGSEV when calling JAVA callback method from native code after multiple calls

I am using JNA to pass a callback function from Java to native code. I am able to call the java inteface method ok, the problem is after about 40 calls of the function i get a SIGSEV and the program terminates.
The SIGSEV occurs at the line when the native code calls the method.
Is this related so some garbage collection on the Java function handle? Is there a way to prevent this?
Note: The closest thread on the sight was "SIGSEV when calling Java method from native pthread". He seemed solve his problem on the native side though by making things global.
I have tried making the java method synchronous but this has not helped. I also modified the native call to launch a pthread and then call the java method. When doing this, the method can be called maybe 1000 times then i get the SIGSEV
on the java side I have
public interface handler extends Callback {
void invoke();
}
static class test_start implements handler {
public synchronized void invoke() {
System.out.println("Hello");
}
}
You are right, that you suspect GC to be your problem, which is also documented in JNA.
Summary: You'll need to keep a strong reference to your Callback Handler on the java side to prevent garbage collection.
The implementation is highly dependent on your architecture. If your handler is global, you can save it in a static field (GC will normally collect static field data only when class is unloaded). If your handler is tied to a concrete java class, you could use a static WeakHashMap to keep the reference until the java object is collected (assuming this also indicates, that the native side will not call the handler anymore). If the handler is tied to a fixed lifecycle, I would implement an AutoCloseable helper object, that unregisters your handler on close.
It should be noted, that in all implementations, you must make sure that your handler is kept referenced. For the AutoClosable implementation running Reference#reachabilityFence​ from the close method after the handler is unregister would be a sane decision.

Suspending an initialisation thread that executes an external method for prolonged period

Due to the deprecated nature of the Thread stop() and suspend() methods, I have become accustomed to implementing a standard cooperative suspension method using the well tested wait/notify methodology. Unfortunately my current project includes an initialisation thread that duplicates a recursive directory structure via a single call to an external method that doesn't return until it has finished and does not implement any kind of wait/notify cooperation.
I'm curious to know what other programmers are tempted to do in this situation, save perhaps reimplementing the external method, as I'm quite tempted to use the Thread.suspend() method and hope the file operations contained within the external method don't hold on to anything critical whilst suspended.
Hmmm...this is a tricky one.
Well do not even try stop() or suspend(). They were deprecated and there are reasons for rightly so. Ideally you shouldn't even be trying wait or notify when you have so many excellent libraries available in java.util.concurrent package.
In your case, you should check the documentation of the external method you are calling to know about the shutdown policy of that library. If none is mentioned then you can probably try interrupting. interrupt will surely work if the external method call makes some blocking calls. Other than it, I see no other way.
Using suspend will only lead to instability rather than aiding anything. Not using it will take more computational power but will be stable atleast.

Signals in Java

I was use C++ signals
sigaction
struct sigaction sigact;
and set all attributes to use signals
now I want to use it in Java what's the equivalent in java
to the include "signal.h"
I have two threads:
one run from the beginning of the program
and the other run at the signal Alarm
I was implement the functionality in C++ using Signals as shown and now I want to implement it using java
Edited to put my Goal:
actually my Goal to run the second Thread When the signal arrives from the first thread
Thus sounds like a typical "XY-Problem".
In plain Java you have no access to OS-signal. They are platform specific and Java strifes to be platform agnostic. Also: calling Java from a signal handler with JNI might be "fun" (as explained in Dwarf Fortress).
So you have to go back to the drawing board and think about what is the problem you want to solve and stop thinking about how to solve it with signals.
That said: if you insist on signals and are not afraid to use internal stuff which might change on a whim: Take a look at sun.misc.Signal.
EDIT Now the question made it clear, that the signalling takes place within one JVM. For this signals are definitely the wrong thing in Java.
So the simplest solution is to create and start the second thread directly from within the first thread. No signalling required.
The next best solution is to code a "rendezvous point" using Object.wait() in the second thread (using any object instance but the Thread itself) and Object.notify() or notifyAll() from the first thread. Searching for these terms in a Java tutorial will bring up enough examples.

Attaching third party thread to vm when using jni

I'm writing a Java program that uses a hardware driver written in c. This hardware driver starts a callback thread, and you can register callback functions to be called when stuff happens. How can I attach this thread to the jvm so that it can call the Java methods for these callbacks? I only have the thread id returned from the start_callbacks() function, returned as an int, but it is the pthread_t used in the call to pthread_create().
One way I found is to use pthread_once on the start of every callback function and attach the thread there. But then there is no way to detach it. I tried to use pthread_cleanup_push/pop, but they need to be called as a pair so that didn't work.
It seems to me that my only option to do this right is to attach and detach the thread at every callback call. Or rewrite the driver somewhat, which I really don't want to do.
Is there something I missed?
That's exactly what the JNI calls AttachCurrentThread() and DetachCurrentThread() are for.
The solution to you problem can be resolved with thread_local storage (C++ 11 and higher). This allows you to attach to an arbitrary thread, and then it will automatically detach when the thread exist (even when you didn't create the thread and have no control over it's life cycle).
A sample example of how to implement that in C++ can be found in my answer here:
https://stackoverflow.com/a/59934966/8367574

Categories

Resources