protected void increaseCounter(Runnable task) { if (!shouldCount(task)) { return; } Settings settings = this.settings; long maxChannelMemorySize = settings.maxChannelMemorySize; int increment = settings.objectSizeEstimator.estimateSize(task); if (task instanceof ChannelEventRunnable) { ChannelEventRunnable eventTask = (ChannelEventRunnable) task; eventTask.estimatedSize = increment; Channel channel = eventTask.getEvent().getChannel(); long channelCounter = getChannelCounter(channel).addAndGet(increment); // System.out.println("IC: " + channelCounter + ", " + increment); if (maxChannelMemorySize != 0 && channelCounter >= maxChannelMemorySize && channel.isOpen()) { if (channel.isReadable()) { // System.out.println("UNREADABLE"); ChannelHandlerContext ctx = eventTask.getContext(); if (ctx.getHandler() instanceof ExecutionHandler) { // readSuspended = true; ctx.setAttachment(Boolean.TRUE); } channel.setReadable(false); } } } else { ((MemoryAwareRunnable) task).estimatedSize = increment; } if (totalLimiter != null) { totalLimiter.increase(increment); } }
/** * Returns {@code true} if and only if the specified {@code task} should be counted to limit the * global and per-channel memory consumption. To override this method, you must call {@code * super.shouldCount()} to make sure important tasks are not counted. */ protected boolean shouldCount(Runnable task) { if (task instanceof ChannelEventRunnable) { ChannelEventRunnable r = (ChannelEventRunnable) task; ChannelEvent e = r.getEvent(); if (e instanceof WriteCompletionEvent) { return false; } else if (e instanceof ChannelStateEvent) { if (((ChannelStateEvent) e).getState() == ChannelState.INTEREST_OPS) { return false; } } } return true; }
protected void decreaseCounter(Runnable task) { if (!shouldCount(task)) { return; } Settings settings = this.settings; long maxChannelMemorySize = settings.maxChannelMemorySize; int increment; if (task instanceof ChannelEventRunnable) { increment = ((ChannelEventRunnable) task).estimatedSize; } else { increment = ((MemoryAwareRunnable) task).estimatedSize; } if (totalLimiter != null) { totalLimiter.decrease(increment); } if (task instanceof ChannelEventRunnable) { ChannelEventRunnable eventTask = (ChannelEventRunnable) task; Channel channel = eventTask.getEvent().getChannel(); long channelCounter = getChannelCounter(channel).addAndGet(-increment); // System.out.println("DC: " + channelCounter + ", " + increment); if (maxChannelMemorySize != 0 && channelCounter < maxChannelMemorySize && channel.isOpen()) { if (!channel.isReadable()) { // System.out.println("READABLE"); ChannelHandlerContext ctx = eventTask.getContext(); if (ctx.getHandler() instanceof ExecutionHandler) { // check if the attachment was set as this means that we suspend the channel from reads. // This only works when // this pool is used with ExecutionHandler but I guess thats good enough for us. // // See #215 if (ctx.getAttachment() != null) { // readSuspended = false; ctx.setAttachment(null); channel.setReadable(true); } } else { channel.setReadable(true); } } } } }