Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: components/cronet/android/java/src/org/chromium/net/CronetUploadDataStream.java

Issue 1777333002: [Cronet] Fix race in UploadDataStream.attachToRequest. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: do getLength() outside the lock. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import android.util.Log; 7 import android.util.Log;
8 8
9 import org.chromium.base.VisibleForTesting; 9 import org.chromium.base.VisibleForTesting;
10 import org.chromium.base.annotations.CalledByNative; 10 import org.chromium.base.annotations.CalledByNative;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 public void onRewindError(Exception exception) { 225 public void onRewindError(Exception exception) {
226 synchronized (mLock) { 226 synchronized (mLock) {
227 checkState(UserCallback.REWIND); 227 checkState(UserCallback.REWIND);
228 onError(exception); 228 onError(exception);
229 } 229 }
230 } 230 }
231 231
232 /** 232 /**
233 * Posts task to application Executor. 233 * Posts task to application Executor.
234 */ 234 */
235 private void postTaskToExecutor(Runnable task) { 235 void postTaskToExecutor(Runnable task) {
236 try { 236 try {
237 mExecutor.execute(task); 237 mExecutor.execute(task);
238 } catch (Throwable e) { 238 } catch (Throwable e) {
239 // Just fail the request. The request is smart enough to handle the 239 // Just fail the request. The request is smart enough to handle the
240 // case where it was already canceled by the embedder. 240 // case where it was already canceled by the embedder.
241 mRequest.onUploadException(e); 241 mRequest.onUploadException(e);
242 } 242 }
243 } 243 }
244 244
245 /** 245 /**
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 throw new IllegalStateException( 286 throw new IllegalStateException(
287 "Method should not be called when read has not completed ."); 287 "Method should not be called when read has not completed .");
288 } 288 }
289 if (mDestroyAdapterPostponed) { 289 if (mDestroyAdapterPostponed) {
290 destroyAdapter(); 290 destroyAdapter();
291 } 291 }
292 } 292 }
293 } 293 }
294 294
295 /** 295 /**
296 * Initializes upload length by getting it from data provider. Always called
297 * on executor thread to allow getLength() to block and/or report errors.
298 * If data provider throws an exception, then it is reported to the request.
xunjieli 2016/03/10 20:32:21 Could you make a note here to say that that no nat
mef 2016/03/10 22:16:30 Done, although mUploadDataStreamAdapter doesn't ex
299 */
300 void initializeWithRequest(final CronetUrlRequest request) {
301 synchronized (mLock) {
302 mRequest = request;
303 mInWhichUserCallback = UserCallback.GET_LENGTH;
304 }
305 try {
306 mLength = mDataProvider.getLength();
307 } catch (Throwable t) {
308 onError(t);
309 }
310 synchronized (mLock) {
311 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK;
312 }
313 }
314
315 /**
296 * Creates native objects and attaches them to the underlying request 316 * Creates native objects and attaches them to the underlying request
297 * adapter object. 317 * adapter object. Always called on executor thread.
298 * TODO(mmenke): If more types of native upload streams are needed, create
299 * an interface with just this method, to minimize CronetURLRequest's
300 * dependencies on each upload stream type.
301 */ 318 */
302 void attachToRequest(final CronetUrlRequest request, final long requestAdapt er, 319 void attachNativeAdapterToRequest(final long requestAdapter) {
303 final Runnable afterAttachCallback) { 320 synchronized (mLock) {
304 mRequest = request; 321 mUploadDataStreamAdapter = nativeAttachUploadDataToRequest(requestAd apter, mLength);
305 postTaskToExecutor(new Runnable() { 322 }
306 @Override
307 public void run() {
308 synchronized (mLock) {
309 mInWhichUserCallback = UserCallback.GET_LENGTH;
310 }
311 try {
312 mLength = mDataProvider.getLength();
313 } catch (Throwable t) {
314 onError(t);
315 }
316 synchronized (mLock) {
317 mInWhichUserCallback = UserCallback.NOT_IN_CALLBACK;
318 mUploadDataStreamAdapter =
319 nativeAttachUploadDataToRequest(requestAdapter, mLen gth);
320 }
321 afterAttachCallback.run();
322 }
323 });
324 } 323 }
325 324
326 /** 325 /**
327 * Creates a native CronetUploadDataStreamAdapter and 326 * Creates a native CronetUploadDataStreamAdapter and
328 * CronetUploadDataStream for testing. 327 * CronetUploadDataStream for testing.
329 * @return the address of the native CronetUploadDataStream object. 328 * @return the address of the native CronetUploadDataStream object.
330 */ 329 */
331 @VisibleForTesting 330 @VisibleForTesting
332 long createUploadDataStreamForTesting() throws IOException { 331 long createUploadDataStreamForTesting() throws IOException {
333 mUploadDataStreamAdapter = nativeCreateAdapterForTesting(); 332 synchronized (mLock) {
334 mLength = mDataProvider.getLength(); 333 mUploadDataStreamAdapter = nativeCreateAdapterForTesting();
335 return nativeCreateUploadDataStreamForTesting(mLength, 334 mLength = mDataProvider.getLength();
336 mUploadDataStreamAdapter); 335 return nativeCreateUploadDataStreamForTesting(mLength, mUploadDataSt reamAdapter);
336 }
337 } 337 }
338 338
339 @VisibleForTesting 339 @VisibleForTesting
340 void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackForTesting ) { 340 void setOnDestroyedCallbackForTesting(Runnable onDestroyedCallbackForTesting ) {
341 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting; 341 mOnDestroyedCallbackForTesting = onDestroyedCallbackForTesting;
342 } 342 }
343 343
344 // Native methods are implemented in upload_data_stream_adapter.cc. 344 // Native methods are implemented in upload_data_stream_adapter.cc.
345 345
346 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter, 346 private native long nativeAttachUploadDataToRequest(long urlRequestAdapter,
347 long length); 347 long length);
348 348
349 private native long nativeCreateAdapterForTesting(); 349 private native long nativeCreateAdapterForTesting();
350 350
351 private native long nativeCreateUploadDataStreamForTesting(long length, 351 private native long nativeCreateUploadDataStreamForTesting(long length,
352 long adapter); 352 long adapter);
353 353
354 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") 354 @NativeClassQualifiedName("CronetUploadDataStreamAdapter")
355 private native void nativeOnReadSucceeded(long nativePtr, 355 private native void nativeOnReadSucceeded(long nativePtr,
356 int bytesRead, boolean finalChunk); 356 int bytesRead, boolean finalChunk);
357 357
358 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") 358 @NativeClassQualifiedName("CronetUploadDataStreamAdapter")
359 private native void nativeOnRewindSucceeded(long nativePtr); 359 private native void nativeOnRewindSucceeded(long nativePtr);
360 360
361 @NativeClassQualifiedName("CronetUploadDataStreamAdapter") 361 @NativeClassQualifiedName("CronetUploadDataStreamAdapter")
362 private static native void nativeDestroy(long nativePtr); 362 private static native void nativeDestroy(long nativePtr);
363 } 363 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698