org.zeromq.ZThread Maven / Gradle / Ivy
package org.zeromq;
import org.zeromq.ZMQ.Socket;
public class ZThread {
public static interface IAttachedRunnable {
public void run(Object[] args, ZContext ctx, Socket pipe);
}
public static interface IDetachedRunnable {
public void run(Object[] args);
}
private static class ShimThread extends Thread {
private ZContext ctx;
private IAttachedRunnable attachedRunnable;
private IDetachedRunnable detachedRunnable;
private Object[] args;
private Socket pipe;
protected ShimThread(ZContext ctx, IAttachedRunnable runnable, Object[] args, Socket pipe) {
assert (ctx != null);
assert (pipe != null);
assert (runnable != null);
this.ctx = ctx;
this.attachedRunnable = runnable;
this.args = args;
this.pipe = pipe;
}
public ShimThread(IDetachedRunnable runnable, Object[] args) {
assert (runnable != null);
this.detachedRunnable = runnable;
this.args = args;
}
@Override
public void run() {
if (attachedRunnable != null) {
try {
attachedRunnable.run(args, ctx, pipe);
} catch (ZMQException e) {
if (e.getErrorCode() != ZMQ.ETERM()) {
throw e;
}
}
ctx.destroy();
} else
detachedRunnable.run(args);
}
}
// --------------------------------------------------------------------------
// Create a detached thread. A detached thread operates autonomously
// and is used to simulate a separate process. It gets no ctx, and no
// pipe.
public static void start(IDetachedRunnable runnable, Object... args) {
// Prepare child thread
Thread shim = new ShimThread(runnable, args);
shim.start();
}
// --------------------------------------------------------------------------
// Create an attached thread. An attached thread gets a ctx and a PAIR
// pipe back to its parent. It must monitor its pipe, and exit if the
// pipe becomes unreadable. Returns pipe, or null if there was an error.
public static Socket fork(ZContext ctx, IAttachedRunnable runnable, Object... args) {
Socket pipe = ctx.createSocket(ZMQ.PAIR);
if (pipe != null) {
pipe.bind(String.format("inproc://zctx-pipe-%d", pipe.hashCode()));
} else {
return null;
}
// Connect child pipe to our pipe
ZContext ccontext = ZContext.shadow(ctx);
Socket cpipe = ccontext.createSocket(ZMQ.PAIR);
if (cpipe == null)
return null;
cpipe.connect(String.format("inproc://zctx-pipe-%d", pipe.hashCode()));
// Prepare child thread
Thread shim = new ShimThread(ccontext, runnable, args, cpipe);
shim.start();
return pipe;
}
}