From owner-freebsd-java@FreeBSD.ORG Fri Aug 8 20:31:46 2008 Return-Path: Delivered-To: freebsd-java@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3118C1065671 for ; Fri, 8 Aug 2008 20:31:46 +0000 (UTC) (envelope-from ariek4u@gmail.com) Received: from an-out-0708.google.com (an-out-0708.google.com [209.85.132.248]) by mx1.freebsd.org (Postfix) with ESMTP id D5CEC8FC15 for ; Fri, 8 Aug 2008 20:31:45 +0000 (UTC) (envelope-from ariek4u@gmail.com) Received: by an-out-0708.google.com with SMTP id b33so227321ana.13 for ; Fri, 08 Aug 2008 13:31:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:mime-version:content-type; bh=vw3eH0fShepgU4K1s+XSueZ1b7P1IqGwHleohYOf6yo=; b=P3MLAqhWLAry1njiSWe/i3vdOpB4T5AmeRLBLT49L0mTyMn3oiITZohUzh5Se+OmfB uzfUT5yK2CdcaDNXdSO1foxgseht6k5jdnOdROEgcDDnEZb0vlUBRh/f2IHX9qynrnbG W2NrGemLM0YRnn1CDqXvDlEW1F3TGYgU4+pY8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type; b=IO2Z1aMB9cmfIyvP/vHQg8WB8UaojZMiZVX3GWD77avzefwAhuRhfipgax6DBvU4N7 FJ5L93ckK5CdBGJ/cljVf6EfElNY8BeqIPMRYS9drdumuVToIl/bLqHZuMnNIt0/A8Sv 8ooCZsCbzY5xmrDVLejXSbVo5K0DnMpo+imbE= Received: by 10.100.33.13 with SMTP id g13mr7404857ang.96.1218226002668; Fri, 08 Aug 2008 13:06:42 -0700 (PDT) Received: by 10.100.213.3 with HTTP; Fri, 8 Aug 2008 13:06:42 -0700 (PDT) Message-ID: <166bb700808081306o7b9e1134s287a8f23042e1a41@mail.gmail.com> Date: Fri, 8 Aug 2008 22:06:42 +0200 From: "Arie Keren" To: freebsd-java@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: NIO Selector problem X-BeenThere: freebsd-java@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting Java to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Aug 2008 20:31:46 -0000 Hi, I'm running Diablo Java(TM) SE Runtime Environment (build 1.6.0_07-b02) on FreeBSD. I have a problem related to Selector: After receiving read event, I remove OP_READ from key.interestOps(), then read the channel and then return the OP_READ to key.interestOps(). After this the selector doesn't wake up on read. This problem can be reproduced with the attached test. The test runs OK on Windows but Fails on FreeBSD. Note that if you comment the lines marked with //1-3, the program runs OK both on Windows and FreeBSD (but of course this causes to much false read invocations). arie import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestSelector { static boolean terminate; public static void main(String[] args) { try { new NioSelector(); Socket socket = new Socket("127.0.0.1", 4000); for (int i=0; i<5; i++) { socket.getOutputStream().write(1); Thread.sleep(500); } terminate = true; socket.close(); } catch (Exception e) { e.printStackTrace(); } System.out.println ((NioSelector.numReads == 5 ? "OK:" : "FAIL:") + NioSelector.numReads); } public static class NioSelector implements Runnable { protected Selector selector; ServerSocketChannel tcpListener; SocketChannel tcpClient; ExecutorService executor; static int numReads; public NioSelector() throws IOException { executor = Executors.newFixedThreadPool(1); selector = Selector.open(); tcpListener = ServerSocketChannel.open(); tcpListener.configureBlocking(false); tcpListener.socket().bind(new InetSocketAddress(4000)); tcpListener.register(selector, SelectionKey.OP_ACCEPT); new Thread(this).start(); } @Override public void run() { while (!terminate) { try { int numKeys = selector.select(1000); if (numKeys == 0) continue; Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); if (key.isAcceptable()) { tcpClient = ((ServerSocketChannel)key.channel()).accept(); tcpClient.configureBlocking(false); tcpClient.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); //1 final SelectionKey fkey = key; executor.execute(new Runnable () { public void run() { ByteBuffer inBuf = ByteBuffer.allocate(1); try { if (tcpClient.read(inBuf) > 0) numReads++; } catch (IOException e) { e.printStackTrace(); } fkey.interestOps(fkey.interestOps() | SelectionKey.OP_READ); //2 selector.wakeup(); //3 } }); } } } catch (Throwable e) { e.printStackTrace(); } } executor.shutdownNow(); } } }