final void detachFromParent() { if (parentStream != null) { parentStream.getChildStreams().remove(this); parentStream = null; } }
final synchronized void decrementWindowSize(int decrement) { // No need for overflow protection here. Decrement can never be larger // the Integer.MAX_VALUE and once windowSize goes negative no further // decrements are permitted windowSize -= decrement; if (log.isDebugEnabled()) { log.debug(sm.getString("abstractStream.windowSizeDec", getConnectionId(), getIdentifier(), Integer.toString(decrement), Long.toString(windowSize))); } }
final boolean isDescendant(AbstractStream stream) { if (childStreams.contains(stream)) { return true; } for (AbstractStream child : childStreams) { if (child.isDescendant(stream)) { return true; } } return false; }
final void rePrioritise(AbstractStream parent, boolean exclusive, int weight) { if (log.isDebugEnabled()) { log.debug(sm.getString("stream.reprioritisation.debug", getConnectionId(), getIdentifier(), Boolean.toString(exclusive), parent.getIdentifier(), Integer.toString(weight))); } // Check if new parent is a descendant of this stream if (isDescendant(parent)) { parent.detachFromParent(); // Cast is always safe since any descendant of this stream must be // an instance of Stream getParentStream().addChild((Stream) parent); } if (exclusive) { // Need to move children of the new parent to be children of this // stream. Slightly convoluted to avoid concurrent modification. Iterator<Stream> parentsChildren = parent.getChildStreams().iterator(); while (parentsChildren.hasNext()) { Stream parentsChild = parentsChildren.next(); parentsChildren.remove(); this.addChild(parentsChild); } } detachFromParent(); parent.addChild(this); this.weight = weight; }
!((Stream) parent).isClosedFinal() && parent.getChildStreams().size() == 0) { streams.remove(parent.getIdentifier()); parent.detachFromParent(); toClose--; if (log.isDebugEnabled()) { candidatesStepTwo.remove(parent.getIdentifier()); parent = parent.getParentStream();
private int allocate(AbstractStream stream, int allocation) { if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.allocate.debug", getConnectionId(), stream.getIdentifier(), Integer.toString(allocation))); getConnectionId(), stream.getIdentifier(), Integer.toString(leftToAllocate))); recipients.addAll(stream.getChildStreams()); recipients.retainAll(backLogStreams.keySet()); if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.allocate.recipient", getConnectionId(), stream.getIdentifier(), recipient.getIdentifier(), Integer.toString(recipient.getWeight()))); totalWeight += recipient.getWeight(); while (iter.hasNext()) { AbstractStream recipient = iter.next(); int share = leftToAllocate * recipient.getWeight() / totalWeight; if (share == 0) {
final void rePrioritise(AbstractStream parent, int weight) { if (log.isDebugEnabled()) { log.debug(sm.getString("stream.reprioritisation.debug", getConnectionId(), getIdentifier(), Boolean.FALSE, parent.getIdentifier(), Integer.toString(weight))); } parent.addChild(this); this.weight = weight; }
streamsToNotify = releaseBackLog((int) (windowSize +increment)); super.incrementWindowSize(increment); if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.releaseBacklog", connectionId, stream.getIdentifier())); if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.notifyAll", connectionId, stream.getIdentifier())); if (log.isDebugEnabled()) { log.debug(sm.getString("upgradeHandler.dispatchWrite", connectionId, stream.getIdentifier()));
@Override final synchronized void incrementWindowSize(int windowSizeIncrement) throws Http2Exception { // If this is zero then any thread that has been trying to write for // this stream will be waiting. Notify that thread it can continue. Use // notify all even though only one thread is waiting to be on the safe // side. boolean notify = getWindowSize() < 1; super.incrementWindowSize(windowSizeIncrement); if (notify && getWindowSize() > 0) { if (coyoteResponse.getWriteListener() == null) { // Blocking, so use notify to release StreamOutputBuffer notifyAll(); } else { // Non-blocking so dispatch coyoteResponse.action(ActionCode.DISPATCH_WRITE, null); // Need to explicitly execute dispatches on the StreamProcessor // as this thread is being processed by an UpgradeProcessor // which won't see this dispatch coyoteResponse.action(ActionCode.DISPATCH_EXECUTE, null); } } }
/** * Increment window size. * @param increment The amount by which the window size should be increased * @throws Http2Exception If the window size is now higher than * the maximum allowed */ synchronized void incrementWindowSize(int increment) throws Http2Exception { // No need for overflow protection here. // Increment can't be more than Integer.MAX_VALUE and once windowSize // goes beyond 2^31-1 an error is triggered. windowSize += increment; if (log.isDebugEnabled()) { log.debug(sm.getString("abstractStream.windowSizeInc", getConnectionId(), getIdentifier(), Integer.toString(increment), Long.toString(windowSize))); } if (windowSize > ConnectionSettingsBase.MAX_WINDOW_SIZE) { String msg = sm.getString("abstractStream.windowSizeTooBig", getConnectionId(), identifier, Integer.toString(increment), Long.toString(windowSize)); if (identifier.intValue() == 0) { throw new ConnectionException(msg, Http2Error.FLOW_CONTROL_ERROR); } else { throw new StreamException( msg, Http2Error.FLOW_CONTROL_ERROR, identifier.intValue()); } } }