001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.mina.common.support;
021
022 import org.apache.mina.common.IoFuture;
023 import org.apache.mina.common.IoSession;
024 import org.apache.mina.common.IoFutureListener;
025
026 import java.util.List;
027 import java.util.ArrayList;
028 import java.util.Iterator;
029
030 /**
031 * A default implementation of {@link org.apache.mina.common.IoFuture}.
032 *
033 * @author The Apache Directory Project (mina-dev@directory.apache.org)
034 */
035 public class DefaultIoFuture implements IoFuture
036 {
037 private final IoSession session;
038 private final Object lock;
039 private List listeners;
040 private Object result;
041 private boolean ready;
042
043
044 /**
045 * Creates a new instance.
046 *
047 * @param session an {@link IoSession} which is associated with this future
048 */
049 public DefaultIoFuture( IoSession session )
050 {
051 this.session = session;
052 this.lock = this;
053 }
054
055 /**
056 * Creates a new instance which uses the specified object as a lock.
057 */
058 public DefaultIoFuture( IoSession session, Object lock )
059 {
060 if( lock == null )
061 {
062 throw new NullPointerException( "lock" );
063 }
064 this.session = session;
065 this.lock = lock;
066 }
067
068 public IoSession getSession()
069 {
070 return session;
071 }
072
073 public Object getLock()
074 {
075 return lock;
076 }
077
078 public void join()
079 {
080 synchronized( lock )
081 {
082 while( !ready )
083 {
084 try
085 {
086 lock.wait();
087 }
088 catch( InterruptedException e )
089 {
090 }
091 }
092 }
093 }
094
095 public boolean join( long timeoutInMillis )
096 {
097 long startTime = ( timeoutInMillis <= 0 ) ? 0 : System
098 .currentTimeMillis();
099 long waitTime = timeoutInMillis;
100
101 synchronized( lock )
102 {
103 if( ready )
104 {
105 return ready;
106 }
107 else if( waitTime <= 0 )
108 {
109 return ready;
110 }
111
112 for( ;; )
113 {
114 try
115 {
116 lock.wait( waitTime );
117 }
118 catch( InterruptedException e )
119 {
120 }
121
122 if( ready )
123 return true;
124 else
125 {
126 waitTime = timeoutInMillis - ( System.currentTimeMillis() - startTime );
127 if( waitTime <= 0 )
128 {
129 return ready;
130 }
131 }
132 }
133 }
134 }
135
136 public boolean isReady()
137 {
138 synchronized( lock )
139 {
140 return ready;
141 }
142 }
143
144 /**
145 * Sets the result of the asynchronous operation, and mark it as finished.
146 */
147 protected void setValue( Object newValue )
148 {
149 synchronized( lock )
150 {
151 // Allow only once.
152 if( ready )
153 {
154 return;
155 }
156
157 result = newValue;
158 ready = true;
159 lock.notifyAll();
160
161 notifyListeners();
162 }
163 }
164
165 /**
166 * Returns the result of the asynchronous operation.
167 */
168 protected Object getValue()
169 {
170 synchronized( lock )
171 {
172 return result;
173 }
174 }
175
176 public void addListener( IoFutureListener listener )
177 {
178 if( listener == null )
179 {
180 throw new NullPointerException( "listener" );
181 }
182
183 synchronized( lock )
184 {
185 if(listeners == null)
186 {
187 listeners = new ArrayList();
188 }
189 listeners.add( listener );
190 if( ready )
191 {
192 listener.operationComplete( this );
193 }
194 }
195 }
196
197 public void removeListener( IoFutureListener listener )
198 {
199 if( listener == null )
200 {
201 throw new NullPointerException( "listener" );
202 }
203
204 synchronized( lock )
205 {
206 listeners.remove( listener );
207 }
208 }
209
210 private void notifyListeners()
211 {
212 synchronized( lock )
213 {
214
215 if(listeners != null)
216 {
217
218 for( Iterator i = listeners.iterator(); i.hasNext(); ) {
219 ( ( IoFutureListener ) i.next() ).operationComplete( this );
220 }
221 }
222 }
223 }
224 }
225
226
|