* @return true if the whole ByteBuffer was written, false if only part of it or none of it was written.
     * @throws IOException
     * @throws InterruptedException
     */
    private synchronized void tryWriteOrClose(DelayedWritesCloses action) throws IOException, InterruptedException {       
        //TODO: make 30 seconds configurable in milliseoncds maybe
        boolean accepted = waitingWriters.offer(action, 30, TimeUnit.SECONDS);
        if(!accepted) {
        	throw new RuntimeException(this+"registered="+registered+" Dropping data, the upstream must be full as our queue is full of writes" +
        			" that are stuck and can't go out(you should NOT call dataChunk.setProcessed in this case so the" +
        			" downstream will slowdown and will not flood you as tcp flow control automatically kicks" +
        			" in which means you will not flood the upstream like you are doing!!!!");
        }
        
        //if not already registered, then register for writes.....
        //NOTE: we must do this after waitingWriters.offer so there is something on the queue to read
        //otherwise, that could be bad.
        if(!registered) {
            registered = true;
            if(log.isLoggable(Level.FINER))
                log.finer(this+"registering channel for write msg cb="+action+" size="+waitingWriters.size());
            getSelectorManager().registerSelectableChannel(this, SelectionKey.OP_WRITE, null, false);
        }
    }