Pooled<ByteBuffer> allocate(byte protoId) { Pooled<ByteBuffer> pooled = channel.allocate(protoId); ByteBuffer buffer = pooled.getResource(); buffer.putShort(messageId); return pooled; }
final InboundMessage inboundMessage; if ((flags & Protocol.MSG_FLAG_NEW) != 0) { if (! openInboundMessage()) { asyncCloseMessage(id); return; nextReceiver = null; try { getExecutor().execute(() -> receiver.handleMessage(RemoteConnectionChannel.this, inboundMessage.messageInputStream)); ok2 = true; } catch (Throwable t) { if (! ok2) freeInboundMessage((short) id);
void closeReads() { int oldState, newState; do { oldState = channelState; if ((oldState & READ_CLOSED) != 0) { return; } newState = oldState | READ_CLOSED; } while (!casState(oldState, newState)); if (oldState == WRITE_CLOSED) { // no channels log.tracef("Closed channel reads on %s (unregistering)", this); unregister(); } else { log.tracef("Closed channel reads on %s", this); } notifyEnd(); }
@Override protected void closeAction() throws IOException { closeReadsAndWrites(); closeMessages(); closeComplete(); }
boolean closeWrites() { int oldState, newState; do { oldState = channelState; if ((oldState & WRITE_CLOSED) != 0) { return false; } newState = oldState | WRITE_CLOSED; } while (!casState(oldState, newState)); if (oldState == READ_CLOSED) { // no channels and read was closed log.tracef("Closed channel writes on %s (unregistering)", this); unregister(); } else { log.tracef("Closed channel writes on %s", this); } return true; }
RemoteConnectionChannel connectionChannel = new RemoteConnectionChannel(handler, connection, channelId, outboundWindow, inboundWindow, outboundMessages, inboundMessages, outboundMessageSize, inboundMessageSize); RemoteConnectionChannel existing = handler.addChannel(connectionChannel); if (existing != null) { refuseService(channelId, "Duplicate ID"); } finally { existing.handleRemoteClose(); message = null; buffer = null; connectionChannel.handleMessageData(messageCopy); break; connectionChannel.handleWindowOpen(message); break; connectionChannel.handleAsyncClose(message); break; connectionChannel.handleRemoteClose(); break; connectionChannel.handleIncomingWriteShutdown(); break; RemoteConnectionChannel newChannel = new RemoteConnectionChannel(handler, connection, channelId, outboundWindow, inboundWindow, outboundMessageCount, inboundMessageCount, outboundMessageSize, inboundMessageSize); handler.putChannel(newChannel); pendingChannel.getResult().setResult(newChannel);
pooled.free(); if (! eofSent && channel.getConnectionHandler().isMessageClose()) { eofSent = true; pooled = allocate(Protocol.MESSAGE_DATA); channel.getRemoteConnection().send(pooled); ok = true; } finally { channel.free(this); if (! released) { released = true; channel.closeOutboundMessage();
public MessageOutputStream writeMessage() throws IOException { int tries = 50; IntIndexMap<OutboundMessage> outboundMessages = this.outboundMessages; openOutboundMessage(); boolean ok = false; try { final Random random = ThreadLocalRandom.current(); while (tries > 0) { final int id = random.nextInt() & 0xfffe; if (! outboundMessages.containsKey(id)) { OutboundMessage message = new OutboundMessage((short) id, this, outboundWindow, maxOutboundMessageSize); OutboundMessage existing = outboundMessages.putIfAbsent(message); if (existing == null) { ok = true; return message; } } tries --; } throw log.channelBusy(); } finally { if (! ok) { closeOutboundMessage(); } } }
private void closeAllChannels() { final ArrayList<RemoteConnectionChannel> list; synchronized (remoteConnection.getLock()) { list = new ArrayList<RemoteConnectionChannel>(channels); } for (RemoteConnectionChannel channel : list) { channel.closeAsync(); } }
void openOutboundMessage() throws IOException { int oldState, newState; do { oldState = channelState; if ((oldState & WRITE_CLOSED) != 0) { throw new NotOpenException("Writes closed"); } final int outboundCount = oldState & OUTBOUND_MESSAGES_MASK; if (outboundCount == maxOutboundMessages) { throw new ChannelBusyException("Too many open outbound writes"); } newState = oldState + ONE_OUTBOUND_MESSAGE; } while (!casState(oldState, newState)); log.tracef("Opened outbound message on %s", this); }
void freeInboundMessage(final short id) { if (inboundMessages.removeKey(id & 0xffff) != null) { closeInboundMessage(); } }
void handleIncomingWriteShutdown() { closeReads(); }
try { RemoteConnectionChannel connectionChannel = new RemoteConnectionChannel(handler, connection, channelId, outboundWindow, inboundWindow, outboundMessages, inboundMessages, outboundMessageSize, inboundMessageSize); RemoteConnectionChannel existing = handler.addChannel(connectionChannel); if (existing != null) { refuseService(channelId, "Duplicate ID"); } finally { existing.handleRemoteClose(); connectionChannel.handleMessageData(pooled); connectionChannel.handleWindowOpen(pooled); break; connectionChannel.handleAsyncClose(pooled); break; connectionChannel.handleRemoteClose(); break; connectionChannel.handleIncomingWriteShutdown(); break; RemoteConnectionChannel newChannel = new RemoteConnectionChannel(handler, connection, channelId, outboundWindow, inboundWindow, outboundMessageCount, inboundMessageCount, outboundMessageSize, inboundMessageSize); handler.putChannel(newChannel); pendingChannel.getResult().setResult(newChannel);
final Connection connection = channel.getRemoteConnection().getConnection(); final boolean badMsgSize = channel.getConnectionHandler().isFaultyMessageSize(); final int msgSize = badMsgSize ? buffer.remaining() : buffer.remaining() - 8; boolean sendCancel = cancelled && ! cancelSent; buffer.put(7, (byte) (buffer.get(7) | Protocol.MSG_FLAG_EOF)); log.tracef("Sending message (with EOF) (%s) to %s", buffer, connection); if (! channel.getConnectionHandler().isMessageClose()) { channel.free(OutboundMessage.this); channel.closeOutboundMessage(); log.trace("Message includes cancel flag"); channel.getRemoteConnection().send(pooledBuffer); ok = true; if (intr) {
@Override protected void closeAction() throws IOException { closeReadsAndWrites(); closeMessages(); closeComplete(); }
boolean closeWrites() { int oldState, newState; do { oldState = channelState; if ((oldState & WRITE_CLOSED) != 0) { return false; } newState = oldState | WRITE_CLOSED; } while (!casState(oldState, newState)); if (oldState == READ_CLOSED) { // no channels and read was closed log.tracef("Closed channel writes on %s (unregistering)", this); unregister(); } else { log.tracef("Closed channel writes on %s", this); } return true; }
public MessageOutputStream writeMessage() throws IOException { int tries = 50; IntIndexMap<OutboundMessage> outboundMessages = this.outboundMessages; openOutboundMessage(); boolean ok = false; try { final Random random = ProtocolUtils.randomHolder.get(); while (tries > 0) { final int id = random.nextInt() & 0xfffe; if (! outboundMessages.containsKey(id)) { OutboundMessage message = new OutboundMessage((short) id, this, outboundWindow, maxOutboundMessageSize); OutboundMessage existing = outboundMessages.putIfAbsent(message); if (existing == null) { ok = true; return message; } } tries --; } throw log.channelBusy(); } finally { if (! ok) { closeOutboundMessage(); } } }
private void unregister() { log.tracef("Unregistering %s", this); closeAsync(); connectionHandler.handleChannelClosed(this); }
boolean openInboundMessage() { int oldState, newState; do { oldState = channelState; if ((oldState & READ_CLOSED) != 0) { log.tracef("Refusing inbound message on %s (reads closed)", this); return false; } final int inboundCount = oldState & INBOUND_MESSAGES_MASK; if (inboundCount == maxInboundMessages) { log.tracef("Refusing inbound message on %s (too many concurrent reads)", this); return false; } newState = oldState + ONE_INBOUND_MESSAGE; } while (!casState(oldState, newState)); log.tracef("Opened inbound message on %s", this); return true; }
void freeInboundMessage(final short id) { if (inboundMessages.removeKey(id & 0xffff) != null) { closeInboundMessage(); } }