zmq.MailboxSafe 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 zmq.pipe.YPipe;
import zmq.util.Errno;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
@Deprecated
public class MailboxSafe implements IMailbox
{
// The pipe to store actual commands.
private final YPipe cpipe;
// Synchronize access to the mailbox from receivers and senders
private final ReentrantLock sync;
// Condition variable to pass signals from writer thread to reader thread.
private final Condition condition;
private final ArrayList signalers;
// mailbox name, for better debugging
private final String name;
private final Errno errno;
public MailboxSafe(Ctx ctx, ReentrantLock sync, String name)
{
this.errno = ctx.errno();
this.cpipe = new YPipe<>(Config.COMMAND_PIPE_GRANULARITY.getValue());
this.sync = sync;
this.condition = this.sync.newCondition();
this.signalers = new ArrayList<>(10);
this.name = name;
// Get the pipe into passive state. That way, if the users starts by
// polling on the associated file descriptor it will get woken up when
// new command is posted.
Command cmd = cpipe.read();
assert (cmd == null);
}
public void addSignaler(Signaler signaler)
{
this.signalers.add(signaler);
}
public void removeSignaler(Signaler signaler)
{
this.signalers.remove(signaler);
}
public void clearSignalers()
{
this.signalers.clear();
}
@Override
public void send(Command cmd)
{
sync.lock();
try {
cpipe.write(cmd, false);
boolean ok = cpipe.flush();
if (!ok) {
condition.signalAll();
for (Signaler signaler : signalers) {
signaler.send();
}
}
}
finally {
sync.unlock();
}
}
@Override
public Command recv(long timeout)
{
Command cmd;
// Try to get the command straight away.
cmd = cpipe.read();
if (cmd != null) {
return cmd;
}
// If the timeout is zero, it will be quicker to release the lock, giving other a chance to send a command
// and immediately relock it.
if (timeout == 0) {
sync.unlock();
sync.lock();
}
else {
try {
// Wait for signal from the command sender.
if (timeout == -1) {
condition.await();
}
else {
condition.await(timeout, TimeUnit.MILLISECONDS);
}
}
catch (InterruptedException e) {
// Restore interrupted state...
Thread.currentThread().interrupt();
errno.set(ZError.EINTR);
return null;
}
}
// Another thread may already fetch the command
cmd = cpipe.read();
if (cmd == null) {
errno.set(ZError.EAGAIN);
return null;
}
return cmd;
}
@Override
public void close()
{
// Work around problem that other threads might still be in our
// send() method, by waiting on the mutex before disappearing.
sync.lock();
sync.unlock();
}
@Override
public String toString()
{
return super.toString() + "[" + name + "]";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy