charlie hunt wrote:
> Repository police again :-)
>
> I think you broke it ...
>
> I'm getting a null pointer exception when running the unit tests.
>
> Null pointer at Context.java(line 251) in method Context.call() which is
> a statement, "ioEvent.attach(null);"
Grr I've tested on two platform :-) Thread race somewhere :-) Working on it.
-- Jeanfrancois
>
> charlie ...
>
> jfarcand_at_dev.java.net wrote:
>> Author: jfarcand
>> Date: 2007-05-31 21:54:41+0000
>> New Revision: 230
>>
>> Modified:
>> trunk/CHANGELOG.txt
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java
>>
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java
>>
>>
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
>>
>>
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java
>>
>>
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java
>>
>>
>> Log:
>> Execute the CallbackHandler using a Pipeline Thread instead of the
>> main thread used by the Selector. This prevent CallbackHandler to lock
>> the main Selector. Also do not recycle IOEvent has the CallbackHandler
>> may try to re-use it latter, which is dangerous.
>>
>> Hopefully I didn't break anything.
>>
>>
>>
>> Modified: trunk/CHANGELOG.txt
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/CHANGELOG.txt?view=diff&rev=230&p1=trunk/CHANGELOG.txt&p2=trunk/CHANGELOG.txt&r1=229&r2=230
>>
>> ==============================================================================
>>
>> --- trunk/CHANGELOG.txt (original)
>> +++ trunk/CHANGELOG.txt 2007-05-31 21:54:41+0000
>> @@ -1,13 +1,18 @@
>> 1.5-SNAPSHOT
>> ------------
>> -+ Added JRuby module to the Project
>> +
>> ++ Client now execute on their own thread instead of the Selector Thread.
>> +(jfarcand)
>> ++ Added RCM/Virtualization support (jfarcand)
>> ++ Added JRuby module to the Project (jfarcand)
>> + Non Blocking Client side support via interface ConnectorHandler -
>> (TCPConnectorHandler, UDPConnectorHandler)
>> -+ ConnectionManagement/Cache added
>> -+ Asynchronous OP_WRITE support added
>> + (TCPConnectorHandler, UDPConnectorHandler) (jfarcand & oleksiys)
>> ++ ConnectionManagement/Cache added and integrated (oleksiys)
>> ++ Asynchronous OP_WRITE support added (jfarcand & oleksiys)
>> + Controller can support more that one SelectorHandler simultaneously
>> -+ Started jruby support
>> -+ Comet API now support asynchronous read/write from a CometHandler
>> +(jfarcand & oleksiys)
>> ++ Started jruby support (jfarcand)
>> ++ Comet API now support asynchronous read/write from a CometHandler
>> (jfarcand)
>>
>> 1.5.0 - 4 May 2007
>> -------------------
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/Context.java
>> 2007-05-31 21:54:41+0000
>> @@ -107,6 +107,13 @@
>> /**
>> + * An optional <code>IOEvent</code> that can be invoked
>> + * before the <code>ProtocolChain</code> is invoked.
>> + */
>> + private IOEvent<Context> ioEvent;
>> + + + /**
>> * Constructor
>> */
>> public Context() {
>> @@ -187,6 +194,7 @@
>> key = null;
>> keyRegistrationState = KeyRegistrationState.REGISTER;
>> protocolChain = null;
>> + ioEvent = null;
>> }
>> @@ -214,14 +222,35 @@
>> * @throws java.lang.Exception Exception thrown by protocol chain
>> */
>> public Object call() throws Exception {
>> - SelectionKey key = this.key;
>> - controller.getSelectionKeyHandler().process(key);
>> - try {
>> - protocolChain.execute(this);
>> + // If a IOEvent has been defined, invoke it first and
>> + // let its associated CallbackHandler decide if the
>> ProtocolChain
>> + // be invoked or not.
>> + try{
>> + if (ioEvent != null && key.attachment() != null){
>> + CallbackHandler callBackHandler =
>> ((CallbackHandler)key.attachment());
>> + if (currentOpType == OpType.OP_READ){
>> + callBackHandler.onRead(ioEvent);
>> + } else if (currentOpType == OpType.OP_WRITE){
>> + callBackHandler.onWrite(ioEvent);
>> + } else if (currentOpType == OpType.OP_CONNECT){
>> + callBackHandler.onConnect(ioEvent);
>> + }
>> + } else {
>> + SelectionKey key = this.key;
>> + controller.getSelectionKeyHandler().process(key);
>> + try {
>> + protocolChain.execute(this);
>> + } finally {
>> +
>> controller.getSelectionKeyHandler().postProcess(key);
>> + }
>> + }
>> } finally {
>> - controller.getSelectionKeyHandler().postProcess(key);
>> + // Prevent the CallbackHandler to re-use the context.
>> + // TODO: This is still dangerous as the Context might
>> have been
>> + // cached by the CallbackHandler.
>> + ioEvent.attach(null);
>> + ioEvent = null;
>> }
>> - return null;
>> }
>> @@ -292,4 +321,17 @@
>> this.pipeline = pipeline;
>> }
>> + + /**
>> + * Set an optional CallbackHandler.
>> + */
>> + protected void setIOEvent(IOEvent<Context> ioEvent){
>> + this.ioEvent = ioEvent;
>> + }
>> + + + protected IOEvent getIOEvent(){
>> + return ioEvent;
>> + }
>> + }
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/IOEvent.java
>> 2007-05-31 21:54:41+0000
>> @@ -43,5 +43,5 @@
>> * Return the current attachment.
>> */
>> public E attachment();
>> - +
>> }
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java
>>
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java
>> 2007-05-31 21:54:41+0000
>> @@ -251,7 +251,6 @@
>> controller = new Controller();
>> controller.setSelectorHandler(new TCPSelectorHandler(true));
>> DefaultPipeline pipeline = new DefaultPipeline();
>> - pipeline.setMaxThreads(1);
>> pipeline.initPipeline();
>> pipeline.startPipeline();
>> controller.setPipeline(pipeline);
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
>>
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
>> 2007-05-31 21:54:41+0000
>> @@ -88,13 +88,6 @@
>> /**
>> - * The list of SelectionKey to register next time the
>> Selector.select is
>> - * invoked.
>> - */
>> - protected ConcurrentLinkedQueue<IOEvent<Context>> ioEvents;
>> - - - /**
>> * The socket tcpDelay.
>> */
>> protected boolean tcpNoDelay = false;
>> @@ -231,7 +224,6 @@
>> public void preSelect(Context ctx) throws IOException {
>> if (selector == null){
>> try{
>> - ioEvents = new
>> ConcurrentLinkedQueue<IOEvent<Context>>();
>> connectorInstanceHandler = new
>> TCPConnectorInstanceHandler();
>> // Create the socket listener
>> @@ -456,16 +448,10 @@
>> // disable OP_READ on key before doing anything else
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
>> if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> final Context context =
>> ctx.getController().pollContext(key);
>> context.setSelectionKey(key);
>> context.setCurrentOpType(Context.OpType.OP_READ);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onRead(ioEvent);
>> - ioEvents.offer(ioEvent);
>> + invokeCallbackHandler(context);
>> return false;
>> } else {
>> return true;
>> @@ -482,16 +468,10 @@
>> // disable OP_WRITE on key before doing anything else
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
>> if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> final Context context =
>> ctx.getController().pollContext(key);
>> context.setSelectionKey(key);
>> context.setCurrentOpType(Context.OpType.OP_WRITE);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onWrite(ioEvent);
>> - ioEvents.offer(ioEvent);
>> + invokeCallbackHandler(context);
>> return false;
>> } else {
>> return true;
>> @@ -506,23 +486,37 @@
>> throws IOException{
>> // disable OP_CONNECT on key before doing anything else
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_CONNECT));
>> + + // No OP_READ nor OP_WRITE allowed yet.
>> + key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
>> + key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
>> + if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> Context context = ctx.getController().pollContext(key);
>> context.setSelectionKey(key);
>> context.setCurrentOpType(Context.OpType.OP_CONNECT);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onConnect(ioEvent);
>> - ioEvents.offer(ioEvent);
>> + invokeCallbackHandler(context);
>> }
>> return false;
>> }
>> /**
>> + * Invoke a CallbackHandler via a Context instance.
>> + */
>> + protected void invokeCallbackHandler(Context context) throws
>> IOException{
>> + IOEvent<Context>ioEvent = createIOEvent();
>> + ioEvent.attach(context);
>> + context.setIOEvent(ioEvent);
>> + try {
>> + context.execute();
>> + } catch (PipelineFullException ex){
>> + throw new IOException(ex.getMessage());
>> + } + }
>> + + + /**
>> * Return an instance of the default <code>ConnectorHandler</code>,
>> * which is the <code>TCPConnectorHandler</code>
>> */
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java
>>
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java
>> 2007-05-31 21:54:41+0000
>> @@ -226,7 +226,6 @@
>> controller = new Controller();
>> controller.setSelectorHandler(new UDPSelectorHandler(true));
>> DefaultPipeline pipeline = new DefaultPipeline();
>> - pipeline.setMaxThreads(1);
>> pipeline.initPipeline();
>> pipeline.startPipeline();
>> controller.setPipeline(pipeline);
>>
>> Modified:
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java
>>
>> Url:
>> https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java?view=diff&rev=230&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java&r1=229&r2=230
>>
>> ==============================================================================
>>
>> ---
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java
>> (original)
>> +++
>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPSelectorHandler.java
>> 2007-05-31 21:54:41+0000
>> @@ -93,7 +93,6 @@
>> public void preSelect(Context ctx) throws IOException {
>> if (selector == null){
>> try{
>> - ioEvents = new
>> ConcurrentLinkedQueue<IOEvent<Context>>();
>> connectorInstanceHandler = new
>> UDPConnectorInstanceHandler();
>> datagramChannel = DatagramChannel.open();
>> datagramChannel.configureBlocking(false);
>> @@ -237,78 +236,6 @@
>> return false;
>> }
>>
>> -
>> - /**
>> - * Handle OP_READ.
>> - */
>> - public boolean onReadInterest(final SelectionKey key,Context ctx)
>> - throws IOException{
>> - // disable OP_READ on key before doing anything else -
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
>> - if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> - final Context context =
>> ctx.getController().pollContext(key);
>> - context.setSelectionKey(key);
>> - context.setCurrentOpType(Context.OpType.OP_CONNECT);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onRead(ioEvent);
>> - ioEvents.offer(ioEvent);
>> - return false;
>> - } else {
>> - return true;
>> - }
>> - }
>> -
>> - - /**
>> - * Handle OP_WRITE.
>> - * - */ - public boolean onWriteInterest(final
>> SelectionKey key, Context ctx)
>> - throws IOException{
>> - // disable OP_WRITE on key before doing anything else
>> - key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
>> - if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> - final Context context =
>> ctx.getController().pollContext(key);
>> - context.setSelectionKey(key);
>> - context.setCurrentOpType(Context.OpType.OP_CONNECT);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onWrite(ioEvent);
>> - ioEvents.offer(ioEvent);
>> - return false;
>> - } else {
>> - return true;
>> - }
>> - }
>> -
>> - - /**
>> - * Handle OP_CONNECT.
>> - */ - public boolean onConnectInterest(final
>> SelectionKey key, Context ctx) - throws IOException{
>> - if (key.attachment() instanceof CallbackHandler){
>> - IOEvent<Context> ioEvent = ioEvents.poll();
>> - final Context context =
>> ctx.getController().pollContext(key);
>> - context.setSelectionKey(key);
>> - context.setCurrentOpType(Context.OpType.OP_CONNECT);
>> - if (ioEvent == null){
>> - ioEvent = createIOEvent();
>> - }
>> - ioEvent.attach(context);
>> - ((CallbackHandler)key.attachment()).onConnect(ioEvent);
>> - ioEvents.offer(ioEvent); - } -
>> return false;
>> - }
>> - /**
>> * A token decribing the protocol supported by an implementation
>> of this
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commits-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: commits-help_at_grizzly.dev.java.net
>>
>>
>