zmq.Signaler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jeromq Show documentation
Show all versions of jeromq Show documentation
Pure Java implementation of libzmq
The newest version!
package zmq;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.concurrent.atomic.AtomicLong;
import zmq.util.Errno;
import zmq.util.Utils;
// This is a cross-platform equivalent to signal_fd. However, as opposed
// to signal_fd there can be at most one signal in the signaler at any
// given moment. Attempt to send a signal before receiving the previous
// one will result in undefined behaviour.
final class Signaler implements Closeable
{
private interface IoOperation
{
O call() throws IOException;
}
// Underlying write & read file descriptor.
private final Pipe.SinkChannel w;
private final Pipe.SourceChannel r;
private final Selector selector;
private final ThreadLocal wdummy = ThreadLocal.withInitial(() -> ByteBuffer.allocate(1));
private final ThreadLocal rdummy = ThreadLocal.withInitial(() -> ByteBuffer.allocate(1));
// Selector.selectNow at every sending message doesn't show enough performance
private final AtomicLong wcursor = new AtomicLong(0);
private long rcursor = 0;
private final Errno errno;
private final int pid;
private final Ctx ctx;
Signaler(Ctx ctx, int pid, Errno errno)
{
this.ctx = ctx;
this.pid = pid;
this.errno = errno;
// Create the socket pair for signaling.
try {
Pipe pipe = Pipe.open();
r = pipe.source();
w = pipe.sink();
// Set both fds to non-blocking mode.
Utils.unblockSocket(w, r);
selector = ctx.createSelector();
r.register(selector, SelectionKey.OP_READ);
}
catch (IOException e) {
throw new ZError.IOException(e);
}
}
private O maksInterrupt(IoOperation operation) throws IOException
{
// This loop try to protect the current thread from external interruption.
// If it happens, it mangles current context internal state.
// So it keep trying until it succeed.
// This must only be called on internal IO (using Pipe)
boolean interrupted = Thread.interrupted();
while (true) {
try {
return operation.call();
}
catch (ClosedByInterruptException e) {
interrupted = true;
}
finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
}
@Override
public void close() throws IOException
{
IOException exception = null;
IoOperation
© 2015 - 2024 Weber Informatics LLC | Privacy Policy