Return-Path: Delivered-To: apmail-mina-commits-archive@locus.apache.org Received: (qmail 25961 invoked from network); 7 Jun 2007 09:23:57 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 7 Jun 2007 09:23:57 -0000 Received: (qmail 85494 invoked by uid 500); 7 Jun 2007 09:24:00 -0000 Delivered-To: apmail-mina-commits-archive@mina.apache.org Received: (qmail 85462 invoked by uid 500); 7 Jun 2007 09:24:00 -0000 Mailing-List: contact commits-help@mina.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@mina.apache.org Delivered-To: mailing list commits@mina.apache.org Received: (qmail 85453 invoked by uid 99); 7 Jun 2007 09:24:00 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Jun 2007 02:24:00 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Jun 2007 02:23:56 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 5A5EC1A981A; Thu, 7 Jun 2007 02:23:36 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r545122 - /mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Date: Thu, 07 Jun 2007 09:23:36 -0000 To: commits@mina.apache.org From: trustin@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070607092336.5A5EC1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: trustin Date: Thu Jun 7 02:23:35 2007 New Revision: 545122 URL: http://svn.apache.org/viewvc?view=rev&rev=545122 Log: Fixed issue: DIRMINA-384 (A possible duplicate event emission in DefaultIoFuture) * Reverted back to the original implementation that uses 'synchronized'. Modified: mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Modified: mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java URL: http://svn.apache.org/viewvc/mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java?view=diff&rev=545122&r1=545121&r2=545122 ============================================================================== --- mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java (original) +++ mina/branches/1.1/core/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java Thu Jun 7 02:23:35 2007 @@ -1,165 +1,193 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.mina.common.support; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.mina.common.IoFuture; -import org.apache.mina.common.IoFutureListener; -import org.apache.mina.common.IoSession; - -/** - * A default implementation of {@link IoFuture}. - * - * @author The Apache Directory Project (mina-dev@directory.apache.org) - * @version $Rev$, $Date$ - */ -public class DefaultIoFuture implements IoFuture -{ - private final IoSession session; - private final CountDownLatch completionLatch = new CountDownLatch( 1 ); - private final List listeners = new CopyOnWriteArrayList(); - private final AtomicBoolean ready = new AtomicBoolean( false ); - - private volatile Object result; - - /** - * Creates a new instance. - * - * @param session an {@link IoSession} which is associated with this future - */ - public DefaultIoFuture( IoSession session ) - { - this.session = session; - } - - public IoSession getSession() - { - return session; - } - - public void join() - { - for( ;; ) - { - try - { - completionLatch.await(); - return; - } - catch( InterruptedException e ) - { - } - } - } - - public boolean join( long timeoutInMillis ) - { - long startTime = ( timeoutInMillis <= 0 ) ? 0 : System - .currentTimeMillis(); - long waitTime = timeoutInMillis; - - for( ;; ) - { - boolean ready = false; - try - { - ready = completionLatch.await( waitTime, TimeUnit.MILLISECONDS ); - } - catch( InterruptedException e ) - { - } - - if( ready ) - return true; - else - { - waitTime = timeoutInMillis - ( System.currentTimeMillis() - startTime ); - if( waitTime <= 0 ) - { - return ready; - } - } - } - } - - public boolean isReady() - { - return ready.get(); - } - - /** - * Sets the result of the asynchronous operation, and mark it as finished. - */ - protected void setValue( Object newValue ) - { - if( ready.compareAndSet( false, true ) ) - { - result = newValue; - completionLatch.countDown(); - notifyListeners(); - } - } - - /** - * Returns the result of the asynchronous operation. - */ - protected Object getValue() - { - return result; - } - - public void addListener( IoFutureListener listener ) - { - if( listener == null ) - { - throw new NullPointerException( "listener" ); - } - - listeners.add( listener ); - - if( ready.get() ) - { - listener.operationComplete( this ); - } - } - - public void removeListener( IoFutureListener listener ) - { - if( listener == null ) - { - throw new NullPointerException( "listener" ); - } - - listeners.remove( listener ); - } - - private void notifyListeners() - { - for( IoFutureListener listener : listeners ) - { - listener.operationComplete( this ); - } - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.common.support; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.mina.common.IoFuture; +import org.apache.mina.common.IoFutureListener; +import org.apache.mina.common.IoSession; + +/** + * A default implementation of {@link IoFuture}. + * + * @author The Apache MINA Project (dev@mina.apache.org) + * @version $Rev$, $Date$ + */ +public class DefaultIoFuture implements IoFuture +{ + private final IoSession session; + private final Object lock; + private final List listeners = new ArrayList(); + private Object result; + private boolean ready; + + /** + * Creates a new instance. + * + * @param session an {@link IoSession} which is associated with this future + */ + public DefaultIoFuture( IoSession session ) + { + this.session = session; + this.lock = this; + } + + public IoSession getSession() + { + return session; + } + + public void join() { + synchronized( lock ) + { + while( !ready ) + { + try + { + lock.wait(); + } + catch( InterruptedException e ) + { + } + } + } + } + + public boolean join(long timeoutMillis) { + long startTime = ( timeoutMillis <= 0 ) ? 0 : System.currentTimeMillis(); + long waitTime = timeoutMillis; + + synchronized( lock ) + { + if( ready ) + { + return ready; + } + else if( waitTime <= 0 ) + { + return ready; + } + + for( ;; ) + { + try + { + lock.wait( waitTime ); + } + catch( InterruptedException e ) + { + } + + if( ready ) { + return true; + } else + { + waitTime = timeoutMillis - ( System.currentTimeMillis() - startTime ); + if( waitTime <= 0 ) + { + return ready; + } + } + } + } + } + + public boolean isReady() + { + synchronized( lock ) + { + return ready; + } + } + + /** + * Sets the result of the asynchronous operation, and mark it as finished. + */ + protected void setValue( Object newValue ) + { + synchronized( lock ) + { + // Allow only once. + if( ready ) + { + return; + } + + result = newValue; + ready = true; + lock.notifyAll(); + + notifyListeners(); + } + } + + /** + * Returns the result of the asynchronous operation. + */ + protected Object getValue() + { + synchronized( lock ) + { + return result; + } + } + + public void addListener( IoFutureListener listener ) + { + if( listener == null ) + { + throw new NullPointerException( "listener" ); + } + + synchronized( lock ) + { + listeners.add( listener ); + if( ready ) + { + listener.operationComplete( this ); + } + } + } + + public void removeListener( IoFutureListener listener ) + { + if( listener == null ) + { + throw new NullPointerException( "listener" ); + } + + synchronized( lock ) + { + listeners.remove( listener ); + } + } + + private void notifyListeners() + { + synchronized( lock ) + { + for (IoFutureListener l : listeners) { + l.operationComplete( this ); + } + } + } +}