use of zmq.pipe.Pipe in project jeromq by zeromq.
the class Server method xrecv.
@Override
protected Msg xrecv() {
Msg msg;
ValueReference<Pipe> pipe = new ValueReference<>();
msg = fq.recvPipe(errno, pipe);
// Drop any messages with more flag
while (msg != null && msg.hasMore()) {
// drop all frames of the current multi-frame message
msg = fq.recvPipe(errno, null);
while (msg != null && msg.hasMore()) {
msg = fq.recvPipe(errno, null);
}
// get the new message
if (msg != null) {
msg = fq.recvPipe(errno, pipe);
}
}
if (msg == null) {
return msg;
}
assert (pipe.get() != null);
int routingId = pipe.get().getRoutingId();
msg.setRoutingId(routingId);
return msg;
}
use of zmq.pipe.Pipe in project jeromq by zeromq.
the class Req method recvReplyPipe.
private Msg recvReplyPipe() {
while (true) {
ValueReference<Pipe> pipe = new ValueReference<>();
Msg msg = super.recvpipe(pipe);
if (msg == null) {
return null;
}
if (replyPipe.get() == null || replyPipe.get() == pipe.get()) {
return msg;
}
}
}
use of zmq.pipe.Pipe in project jeromq by zeromq.
the class FQ method recvPipe.
public Msg recvPipe(Errno errno, ValueReference<Pipe> pipe) {
// Round-robin over the pipes to get the next message.
while (active > 0) {
// Try to fetch new message. If we've already read part of the message
// subsequent part should be immediately available.
final Pipe currentPipe = pipes.get(current);
final Msg msg = currentPipe.read();
final boolean fetched = msg != null;
// the 'current' pointer.
if (fetched) {
if (pipe != null) {
pipe.set(currentPipe);
}
more = msg.hasMore();
if (!more) {
lastIn = currentPipe;
// happens when multiple threads receive messages
assert (active > 0);
current = (current + 1) % active;
}
return msg;
}
// we should get the remaining parts without blocking.
assert (!more);
active--;
Collections.swap(pipes, current, active);
if (current == active) {
current = 0;
}
}
// No message is available. Initialize the output parameter
// to be a 0-byte message.
errno.set(ZError.EAGAIN);
return null;
}
use of zmq.pipe.Pipe in project jeromq by zeromq.
the class SocketBase method connectInternal.
private boolean connectInternal(String addr) {
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
options.mechanism.check(options);
// Process pending commands, if any.
boolean brc = processCommands(0, false, null);
if (!brc) {
return false;
}
SimpleURI uri = SimpleURI.create(addr);
String address = uri.getAddress();
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null || !protocol.valid) {
return false;
}
if (protocol == NetProtocol.inproc) {
// TODO: inproc connect is specific with respect to creating pipes
// as there's no 'reconnect' functionality implemented. Once that
// is in place we should follow generic pipe creation algorithm.
// Find the peer endpoint.
Ctx.Endpoint peer = findEndpoint(addr);
// The total HWM for an inproc connection should be the sum of
// the binder's HWM and the connector's HWM.
int sndhwm = 0;
if (peer.socket == null) {
sndhwm = options.sendHwm;
} else if (options.sendHwm != 0 && peer.options.recvHwm != 0) {
sndhwm = options.sendHwm + peer.options.recvHwm;
}
int rcvhwm = 0;
if (peer.socket == null) {
rcvhwm = options.recvHwm;
} else if (options.recvHwm != 0 && peer.options.sendHwm != 0) {
rcvhwm = options.recvHwm + peer.options.sendHwm;
}
// Create a bi-directional pipe to connect the peers.
ZObject[] parents = { this, peer.socket == null ? this : peer.socket };
boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
int[] hwms = { conflate ? -1 : sndhwm, conflate ? -1 : rcvhwm };
boolean[] conflates = { conflate, conflate };
Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
// Attach local end of the pipe to this socket object.
attachPipe(pipes[0], true);
if (peer.socket == null) {
// The peer doesn't exist yet so we don't know whether
// to send the identity message or not. To resolve this,
// we always send our identity and drop it later if
// the peer doesn't expect it.
Msg id = new Msg(options.identitySize);
id.put(options.identity, 0, options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[0].write(id);
assert (written);
pipes[0].flush();
// If set, send the hello msg of the local socket to the peer.
if (options.canSendHelloMsg && options.helloMsg != null) {
written = pipes[0].write(options.helloMsg);
assert (written);
pipes[0].flush();
}
pendConnection(addr, new Ctx.Endpoint(this, options), pipes);
} else {
// If required, send the identity of the peer to the local socket.
if (peer.options.recvIdentity) {
Msg id = new Msg(options.identitySize);
id.put(options.identity, 0, options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[0].write(id);
assert (written);
pipes[0].flush();
}
// If required, send the identity of the local socket to the peer.
if (options.recvIdentity) {
Msg id = new Msg(peer.options.identitySize);
id.put(peer.options.identity, 0, peer.options.identitySize);
id.setFlags(Msg.IDENTITY);
boolean written = pipes[1].write(id);
assert (written);
pipes[1].flush();
}
// If set, send the hello msg of the local socket to the peer.
if (options.canSendHelloMsg && options.helloMsg != null) {
boolean written = pipes[0].write(options.helloMsg);
assert (written);
pipes[0].flush();
}
// If set, send the hello msg of the peer to the local socket.
if (peer.options.canSendHelloMsg && peer.options.helloMsg != null) {
boolean written = pipes[1].write(peer.options.helloMsg);
assert (written);
pipes[1].flush();
}
if (peer.options.canReceiveDisconnectMsg && peer.options.disconnectMsg != null) {
pipes[0].setDisconnectMsg(peer.options.disconnectMsg);
}
// Attach remote end of the pipe to the peer socket. Note that peer's
// seqnum was incremented in findEndpoint function. We don't need it
// increased here.
sendBind(peer.socket, pipes[1], false);
}
// Save last endpoint URI
options.lastEndpoint = addr;
// remember inproc connections for disconnect
inprocs.insert(addr, pipes[0]);
return true;
}
boolean isSingleConnect = options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_SUB || options.type == ZMQ.ZMQ_REQ;
if (isSingleConnect) {
if (endpoints.hasValues(addr)) {
// nonsensical results.
return true;
}
}
// Choose the I/O thread to run the session in.
IOThread ioThread = chooseIoThread(options.affinity);
if (ioThread == null) {
errno.set(ZError.EMTHREAD);
return false;
}
Address paddr = new Address(protocol, address);
// Resolve address (if needed by the protocol)
protocol.resolve(paddr, options.ipv6);
// Create session.
SessionBase session = Sockets.createSession(ioThread, true, this, options, paddr);
assert (session != null);
// PGM does not support subscription forwarding; ask for all data to be
// sent to this pipe. (same for NORM, currently?)
boolean subscribe2all = protocol.subscribe2all;
Pipe newpipe = null;
if (options.immediate || subscribe2all) {
// Create a bi-directional pipe.
ZObject[] parents = { this, session };
boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
int[] hwms = { conflate ? -1 : options.sendHwm, conflate ? -1 : options.recvHwm };
boolean[] conflates = { conflate, conflate };
Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
// Attach local end of the pipe to the socket object.
attachPipe(pipes[0], subscribe2all, true);
newpipe = pipes[0];
// Attach remote end of the pipe to the session object later on.
session.attachPipe(pipes[1]);
}
// Save last endpoint URI
options.lastEndpoint = paddr.toString();
addEndpoint(addr, session, newpipe);
return true;
}
use of zmq.pipe.Pipe in project jeromq by zeromq.
the class SocketBase method termEndpoint.
public final boolean termEndpoint(String addr) {
lock();
try {
// Check whether the library haven't been shut down yet.
if (ctxTerminated) {
errno.set(ZError.ETERM);
return false;
}
// Check whether endpoint address passed to the function is valid.
if (addr == null) {
errno.set(ZError.EINVAL);
return false;
}
// Process pending commands, if any, since there could be pending unprocessed processOwn()'s
// (from launchChild() for example) we're asked to terminate now.
boolean rc = processCommands(0, false, null);
if (!rc) {
return false;
}
SimpleURI uri = SimpleURI.create(addr);
NetProtocol protocol = checkProtocol(uri.getProtocol());
if (protocol == null) {
return false;
}
// Disconnect an inproc socket
if (protocol == NetProtocol.inproc) {
if (unregisterEndpoint(addr, this)) {
return true;
}
Collection<Pipe> olds = inprocs.remove(addr);
if (olds == null || olds.isEmpty()) {
errno.set(ZError.ENOENT);
return false;
} else {
for (Pipe old : olds) {
old.sendDisconnectMsg();
old.terminate(true);
}
}
return true;
}
String resolvedAddress = addr;
// socket is connected or bound, try with both.
if (protocol == NetProtocol.tcp) {
boolean endpoint = endpoints.hasValues(resolvedAddress);
if (!endpoint) {
// TODO V4 resolve TCP address when unbinding
IZAddress address = protocol.zresolve(uri.getAddress(), options.ipv6);
resolvedAddress = address.address().toString();
endpoint = endpoints.hasValues(resolvedAddress);
if (!endpoint) {
// no luck, try with local resolution
InetSocketAddress socketAddress = address.resolve(uri.getAddress(), options.ipv6, true);
resolvedAddress = socketAddress.toString();
}
}
}
// Find the endpoints range (if any) corresponding to the addr_ string.
Collection<EndpointPipe> eps = endpoints.remove(resolvedAddress);
if (eps == null || eps.isEmpty()) {
errno.set(ZError.ENOENT);
return false;
} else {
// If we have an associated pipe, terminate it.
for (EndpointPipe ep : eps) {
if (ep.pipe != null) {
ep.pipe.terminate(false);
}
termChild(ep.endpoint);
}
}
return true;
} finally {
unlock();
}
}
Aggregations