users@grizzly.java.net

Having trouble with ZipException/File Descriptor leak in Grizzly

From: Bill Simons <bill.simons_at_gmail.com>
Date: Tue, 21 Apr 2009 09:34:39 -0400

Continuing this thread:
http://forums.java.net/jive/thread.jspa?threadID=60501&tstart=0

We have two filters in the chain:

public class GameProtocolFilter extends ParserProtocolFilter {

    private GameProtocolParser gameProtocolParser;

    public GameProtocolFilter(GameProtocolParser gpp) {
        super();
        this.gameProtocolParser = gpp;
    }

    public ProtocolParser newProtocolParser() {
        return new ProtocolParser() {

            private ByteBuffer buffer = null;
            private boolean expectingMoreData = false;
            private boolean hasMoreBytesToParse = false;
            private Action action = null;

            public boolean isExpectingMoreData() {
                return expectingMoreData;
            }

            public boolean hasMoreBytesToParse() {
                return hasMoreBytesToParse;
            }

            public Object getNextMessage() {
                return action;
            }

            public boolean hasNextMessage() {
                if (buffer == null) {
                    return false;
                }

                ByteBuffer dup = buffer.duplicate();

                if (buffer.position() == 0) {
                    expectingMoreData = true;
                    return false;
                }

                dup.flip();
                if (dup.remaining() < 4) {
                    expectingMoreData = true;
                    return false;
                }
                int size = dup.getInt();
                if (size == 0 || dup.remaining() < size) {
                    expectingMoreData = true;
                    return false;
                }

                byte typeByte = dup.get();
                dup.position(0);
                byte[] testData = new byte[size + 4];
                dup.get(testData);

                action = gameProtocolParser.parseAction(typeByte, testData);

                hasMoreBytesToParse = dup.hasRemaining();
                return (action != null);
            }

            public void startBuffer(ByteBuffer byteBuffer) {
                buffer = byteBuffer;
            }

            public boolean releaseBuffer() {
                buffer = null;
                action = null;
                expectingMoreData = false;
                hasMoreBytesToParse = false;
                return false;
            }
        };
    }
}


The next filter in our chain dispatches the parsed message to another
thread pool:
 public boolean execute(Context ctx) throws IOException {
        final Action action = (Action)
ctx.removeAttribute(ProtocolParser.MESSAGE);
        final Context workerContext = ctx;
        ctx.incrementRefCount();
        executorService.execute(new Runnable() {
            public void run() {
                action.handle(handler, workerContext);
                workerContext.getController().returnContext(workerContext);
            }
        });
        return false;
}

I think these are pretty straightforward but maybe we're missing some
fundamental?

We're using a grizzly controller with a DefaultPipeline and
BaseSelectionKeyHandler.

Thanks for your help.