dev@grizzly.java.net

Re: svn commit: r230 - trunk: . modules/grizzly/src/main/java/com/sun/grizzly

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Thu, 31 May 2007 18:18:55 -0400

Fixed :-)

I've merged and forgot to clean and build, and test!

-- Jeanfrancois

Jeanfrancois Arcand wrote:
>
>
> 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
>>>
>>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>