| 229 | } |
| 230 | |
| 231 | @Override |
| 232 | public void start(ClientStreamListener listener) { |
| 233 | checkNotNull(listener, "listener"); |
| 234 | checkState(this.listener == null, "already started"); |
| 235 | |
| 236 | Status savedError; |
| 237 | boolean savedPassThrough; |
| 238 | synchronized (this) { |
| 239 | // If error != null, then cancel() has been called and was unable to close the listener |
| 240 | savedError = error; |
| 241 | savedPassThrough = passThrough; |
| 242 | if (!savedPassThrough) { |
| 243 | listener = delayedListener = new DelayedStreamListener(listener); |
| 244 | } |
| 245 | this.listener = listener; |
| 246 | startTimeNanos = System.nanoTime(); |
| 247 | } |
| 248 | if (savedError != null) { |
| 249 | listener.closed(savedError, RpcProgress.PROCESSED, new Metadata()); |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | if (savedPassThrough) { |
| 254 | internalStart(listener); |
| 255 | } // else internalStart() will be called by setStream |
| 256 | } |
| 257 | |
| 258 | /** |
| 259 | * Starts stream without synchronization. {@code listener} should be same instance as {@link |