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

Side by Side Diff: components/cronet/android/cronet_bidirectional_stream_adapter.cc

Issue 1969893002: Remove unnecessary array allocation in cronet_bidirectional_stream_adapter.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add include vector Created 4 years, 7 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 #include "cronet_bidirectional_stream_adapter.h" 5 #include "cronet_bidirectional_stream_adapter.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 template <typename JavaArrayType> 42 template <typename JavaArrayType>
43 size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) { 43 size_t SafeGetArrayLength(JNIEnv* env, JavaArrayType jarray) {
44 DCHECK(jarray); 44 DCHECK(jarray);
45 jsize length = env->GetArrayLength(jarray); 45 jsize length = env->GetArrayLength(jarray);
46 DCHECK_GE(length, 0) << "Invalid array length: " << length; 46 DCHECK_GE(length, 0) << "Invalid array length: " << length;
47 return static_cast<size_t>(std::max(0, length)); 47 return static_cast<size_t>(std::max(0, length));
48 } 48 }
49 49
50 } // namespace 50 } // namespace
51 51
52 PendingWriteData::PendingWriteData(JNIEnv* env,
53 jobjectArray jwrite_buffer_list,
54 jintArray jwrite_buffer_pos_list,
55 jintArray jwrite_buffer_limit_list,
56 jboolean jwrite_end_of_stream) {
57 this->jwrite_buffer_list.Reset(env, jwrite_buffer_list);
58 this->jwrite_buffer_pos_list.Reset(env, jwrite_buffer_pos_list);
59 this->jwrite_buffer_limit_list.Reset(env, jwrite_buffer_limit_list);
60 this->jwrite_end_of_stream = jwrite_end_of_stream;
61 }
62
63 PendingWriteData::~PendingWriteData() {
64 // Reset global references.
65 jwrite_buffer_list.Reset();
66 jwrite_buffer_pos_list.Reset();
67 jwrite_buffer_limit_list.Reset();
68 }
69
52 static jlong CreateBidirectionalStream( 70 static jlong CreateBidirectionalStream(
53 JNIEnv* env, 71 JNIEnv* env,
54 const base::android::JavaParamRef<jobject>& jbidi_stream, 72 const base::android::JavaParamRef<jobject>& jbidi_stream,
55 jlong jurl_request_context_adapter, 73 jlong jurl_request_context_adapter,
56 jboolean jdisable_auto_flush) { 74 jboolean jdisable_auto_flush) {
57 CronetURLRequestContextAdapter* context_adapter = 75 CronetURLRequestContextAdapter* context_adapter =
58 reinterpret_cast<CronetURLRequestContextAdapter*>( 76 reinterpret_cast<CronetURLRequestContextAdapter*>(
59 jurl_request_context_adapter); 77 jurl_request_context_adapter);
60 DCHECK(context_adapter); 78 DCHECK(context_adapter);
61 79
(...skipping 10 matching lines...) Expand all
72 } 90 }
73 91
74 CronetBidirectionalStreamAdapter::CronetBidirectionalStreamAdapter( 92 CronetBidirectionalStreamAdapter::CronetBidirectionalStreamAdapter(
75 CronetURLRequestContextAdapter* context, 93 CronetURLRequestContextAdapter* context,
76 JNIEnv* env, 94 JNIEnv* env,
77 const base::android::JavaParamRef<jobject>& jbidi_stream, 95 const base::android::JavaParamRef<jobject>& jbidi_stream,
78 bool disable_auto_flush) 96 bool disable_auto_flush)
79 : context_(context), 97 : context_(context),
80 owner_(env, jbidi_stream), 98 owner_(env, jbidi_stream),
81 disable_auto_flush_(disable_auto_flush), 99 disable_auto_flush_(disable_auto_flush),
82 write_end_of_stream_(false),
83 stream_failed_(false) {} 100 stream_failed_(false) {}
84 101
85 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() { 102 CronetBidirectionalStreamAdapter::~CronetBidirectionalStreamAdapter() {
86 DCHECK(context_->IsOnNetworkThread()); 103 DCHECK(context_->IsOnNetworkThread());
87 } 104 }
88 105
89 jint CronetBidirectionalStreamAdapter::Start( 106 jint CronetBidirectionalStreamAdapter::Start(
90 JNIEnv* env, 107 JNIEnv* env,
91 const base::android::JavaParamRef<jobject>& jcaller, 108 const base::android::JavaParamRef<jobject>& jcaller,
92 const base::android::JavaParamRef<jstring>& jurl, 109 const base::android::JavaParamRef<jstring>& jurl,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 jboolean jend_of_stream) { 174 jboolean jend_of_stream) {
158 size_t buffers_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); 175 size_t buffers_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
159 size_t pos_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); 176 size_t pos_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
160 size_t limit_array_size = SafeGetArrayLength(env, jbyte_buffers.obj()); 177 size_t limit_array_size = SafeGetArrayLength(env, jbyte_buffers.obj());
161 if (buffers_array_size != pos_array_size || 178 if (buffers_array_size != pos_array_size ||
162 buffers_array_size != limit_array_size) { 179 buffers_array_size != limit_array_size) {
163 DLOG(ERROR) << "Illegal arguments."; 180 DLOG(ERROR) << "Illegal arguments.";
164 return JNI_FALSE; 181 return JNI_FALSE;
165 } 182 }
166 183
167 IOBufferWithByteBufferList buffers; 184 std::unique_ptr<PendingWriteData> pending_write_data;
185 pending_write_data.reset(
186 new PendingWriteData(env, jbyte_buffers.obj(), jbyte_buffers_pos.obj(),
187 jbyte_buffers_limit.obj(), jend_of_stream));
168 for (size_t i = 0; i < buffers_array_size; ++i) { 188 for (size_t i = 0; i < buffers_array_size; ++i) {
169 ScopedJavaLocalRef<jobject> jbuffer( 189 ScopedJavaLocalRef<jobject> jbuffer(
170 env, env->GetObjectArrayElement(jbyte_buffers, i)); 190 env, env->GetObjectArrayElement(
191 pending_write_data->jwrite_buffer_list.obj(), i));
171 void* data = env->GetDirectBufferAddress(jbuffer.obj()); 192 void* data = env->GetDirectBufferAddress(jbuffer.obj());
172 if (!data) 193 if (!data)
173 return JNI_FALSE; 194 return JNI_FALSE;
174 jint pos; 195 jint pos;
175 env->GetIntArrayRegion(jbyte_buffers_pos.obj(), i, 1, &pos); 196 env->GetIntArrayRegion(pending_write_data->jwrite_buffer_pos_list.obj(), i,
197 1, &pos);
176 jint limit; 198 jint limit;
177 env->GetIntArrayRegion(jbyte_buffers_limit.obj(), i, 1, &limit); 199 env->GetIntArrayRegion(pending_write_data->jwrite_buffer_limit_list.obj(),
200 i, 1, &limit);
178 DCHECK_LE(pos, limit); 201 DCHECK_LE(pos, limit);
179 scoped_refptr<IOBufferWithByteBuffer> write_buffer( 202 scoped_refptr<net::WrappedIOBuffer> write_buffer(
180 new IOBufferWithByteBuffer( 203 new net::WrappedIOBuffer(static_cast<char*>(data) + pos));
181 env, base::android::JavaParamRef<jobject>(env, jbuffer.Release()), 204 pending_write_data->write_buffer_list.push_back(write_buffer);
182 data, pos, limit)); 205 pending_write_data->write_buffer_len_list.push_back(limit - pos);
183 buffers.push_back(write_buffer);
184 } 206 }
207
185 context_->PostTaskToNetworkThread( 208 context_->PostTaskToNetworkThread(
186 FROM_HERE, 209 FROM_HERE,
187 base::Bind(&CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread, 210 base::Bind(&CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread,
188 base::Unretained(this), buffers, jend_of_stream)); 211 base::Unretained(this),
189 212 base::Passed(std::move(pending_write_data))));
190 return JNI_TRUE; 213 return JNI_TRUE;
191 } 214 }
192 215
193 void CronetBidirectionalStreamAdapter::Destroy( 216 void CronetBidirectionalStreamAdapter::Destroy(
194 JNIEnv* env, 217 JNIEnv* env,
195 const base::android::JavaParamRef<jobject>& jcaller, 218 const base::android::JavaParamRef<jobject>& jcaller,
196 jboolean jsend_on_canceled) { 219 jboolean jsend_on_canceled) {
197 // Destroy could be called from any thread, including network thread (if 220 // Destroy could be called from any thread, including network thread (if
198 // posting task to executor throws an exception), but is posted, so |this| 221 // posting task to executor throws an exception), but is posted, so |this|
199 // is valid until calling task is complete. Destroy() is always called from 222 // is valid until calling task is complete. Destroy() is always called from
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read, 270 env, owner_.obj(), read_buffer_->byte_buffer(), bytes_read,
248 read_buffer_->initial_position(), read_buffer_->initial_limit(), 271 read_buffer_->initial_position(), read_buffer_->initial_limit(),
249 bidi_stream_->GetTotalReceivedBytes()); 272 bidi_stream_->GetTotalReceivedBytes());
250 // Free the read buffer. This lets the Java ByteBuffer be freed, if the 273 // Free the read buffer. This lets the Java ByteBuffer be freed, if the
251 // embedder releases it, too. 274 // embedder releases it, too.
252 read_buffer_ = nullptr; 275 read_buffer_ = nullptr;
253 } 276 }
254 277
255 void CronetBidirectionalStreamAdapter::OnDataSent() { 278 void CronetBidirectionalStreamAdapter::OnDataSent() {
256 DCHECK(context_->IsOnNetworkThread()); 279 DCHECK(context_->IsOnNetworkThread());
257 DCHECK(!write_buffer_list_.empty()); 280 DCHECK(pending_write_data_);
258 281
259 JNIEnv* env = base::android::AttachCurrentThread(); 282 JNIEnv* env = base::android::AttachCurrentThread();
260 base::android::ScopedJavaLocalRef<jclass> byte_buffer_clazz(
261 env, env->FindClass("java/nio/ByteBuffer"));
262 size_t size = write_buffer_list_.size();
263 jobjectArray jbuffer_array =
264 env->NewObjectArray(size, byte_buffer_clazz.obj(), NULL);
265 base::android::CheckException(env);
266 std::vector<int> initial_positions;
267 std::vector<int> initial_limits;
268 for (size_t i = 0; i < size; ++i) {
269 env->SetObjectArrayElement(jbuffer_array, i,
270 write_buffer_list_[i]->byte_buffer());
271 initial_positions.push_back(write_buffer_list_[i]->initial_position());
272 initial_limits.push_back(write_buffer_list_[i]->initial_limit());
273 }
274 ScopedJavaLocalRef<jobjectArray> jbuffers(env, jbuffer_array);
275 ScopedJavaLocalRef<jintArray> jinitial_positions =
276 base::android::ToJavaIntArray(env, initial_positions);
277 ScopedJavaLocalRef<jintArray> jinitial_limits =
278 base::android::ToJavaIntArray(env, initial_limits);
279 // Call into Java. 283 // Call into Java.
280 cronet::Java_CronetBidirectionalStream_onWritevCompleted( 284 cronet::Java_CronetBidirectionalStream_onWritevCompleted(
281 env, owner_.obj(), jbuffers.obj(), jinitial_positions.obj(), 285 env, owner_.obj(), pending_write_data_->jwrite_buffer_list.obj(),
282 jinitial_limits.obj(), write_end_of_stream_); 286 pending_write_data_->jwrite_buffer_pos_list.obj(),
283 // Free the write buffers. This lets the Java ByteBuffer be freed, if the 287 pending_write_data_->jwrite_buffer_limit_list.obj(),
288 pending_write_data_->jwrite_end_of_stream);
289 // Free the java objects. This lets the Java ByteBuffers be freed, if the
284 // embedder releases it, too. 290 // embedder releases it, too.
285 write_buffer_list_.clear(); 291 pending_write_data_.reset();
286 } 292 }
287 293
288 void CronetBidirectionalStreamAdapter::OnTrailersReceived( 294 void CronetBidirectionalStreamAdapter::OnTrailersReceived(
289 const net::SpdyHeaderBlock& response_trailers) { 295 const net::SpdyHeaderBlock& response_trailers) {
290 DCHECK(context_->IsOnNetworkThread()); 296 DCHECK(context_->IsOnNetworkThread());
291 JNIEnv* env = base::android::AttachCurrentThread(); 297 JNIEnv* env = base::android::AttachCurrentThread();
292 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived( 298 cronet::Java_CronetBidirectionalStream_onResponseTrailersReceived(
293 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj()); 299 env, owner_.obj(), GetHeadersArray(env, response_trailers).obj());
294 } 300 }
295 301
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 return; 339 return;
334 340
335 if (bytes_read < 0) { 341 if (bytes_read < 0) {
336 OnFailed(bytes_read); 342 OnFailed(bytes_read);
337 return; 343 return;
338 } 344 }
339 OnDataRead(bytes_read); 345 OnDataRead(bytes_read);
340 } 346 }
341 347
342 void CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread( 348 void CronetBidirectionalStreamAdapter::WritevDataOnNetworkThread(
343 const IOBufferWithByteBufferList& write_buffer_list, 349 std::unique_ptr<PendingWriteData> pending_write_data) {
344 bool end_of_stream) {
345 DCHECK(context_->IsOnNetworkThread()); 350 DCHECK(context_->IsOnNetworkThread());
346 DCHECK(write_buffer_list_.empty()); 351 DCHECK(pending_write_data);
347 DCHECK(!write_buffer_list.empty()); 352 DCHECK(!pending_write_data_);
348 DCHECK(!write_end_of_stream_);
349 353
350 if (stream_failed_) { 354 if (stream_failed_) {
351 // If stream failed between the time when WritevData is invoked and 355 // If stream failed between the time when WritevData is invoked and
352 // WritevDataOnNetworkThread is executed, do not call into |bidi_stream_| 356 // WritevDataOnNetworkThread is executed, do not call into |bidi_stream_|
353 // since the underlying stream might have been destroyed. Do not invoke 357 // since the underlying stream might have been destroyed. Do not invoke
354 // Java callback either, since onError is posted when |stream_failed_| is 358 // Java callback either, since onError is posted when |stream_failed_| is
355 // set to true. 359 // set to true.
356 return; 360 return;
357 } 361 }
358 362
359 write_end_of_stream_ = end_of_stream; 363 pending_write_data_ = std::move(pending_write_data);
360 std::vector<net::IOBuffer*> buffers; 364 bool end_of_stream = pending_write_data_->jwrite_end_of_stream == JNI_TRUE;
361 std::vector<int> lengths; 365 if (pending_write_data_->write_buffer_list.size() == 1) {
362 for (const auto& buffer : write_buffer_list) { 366 bidi_stream_->SendData(pending_write_data_->write_buffer_list[0],
363 write_buffer_list_.push_back(buffer); 367 pending_write_data_->write_buffer_len_list[0],
364 buffers.push_back(buffer.get()); 368 end_of_stream);
365 lengths.push_back(buffer->initial_limit() - buffer->initial_position());
366 }
367 if (buffers.size() == 1) {
368 bidi_stream_->SendData(buffers[0], lengths[0], end_of_stream);
369 } else { 369 } else {
370 bidi_stream_->SendvData(buffers, lengths, end_of_stream); 370 bidi_stream_->SendvData(pending_write_data_->write_buffer_list,
371 pending_write_data_->write_buffer_len_list,
372 end_of_stream);
371 } 373 }
372 } 374 }
373 375
374 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread( 376 void CronetBidirectionalStreamAdapter::DestroyOnNetworkThread(
375 bool send_on_canceled) { 377 bool send_on_canceled) {
376 DCHECK(context_->IsOnNetworkThread()); 378 DCHECK(context_->IsOnNetworkThread());
377 if (send_on_canceled) { 379 if (send_on_canceled) {
378 JNIEnv* env = base::android::AttachCurrentThread(); 380 JNIEnv* env = base::android::AttachCurrentThread();
379 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj()); 381 cronet::Java_CronetBidirectionalStream_onCanceled(env, owner_.obj());
380 } 382 }
381 delete this; 383 delete this;
382 } 384 }
383 385
384 base::android::ScopedJavaLocalRef<jobjectArray> 386 base::android::ScopedJavaLocalRef<jobjectArray>
385 CronetBidirectionalStreamAdapter::GetHeadersArray( 387 CronetBidirectionalStreamAdapter::GetHeadersArray(
386 JNIEnv* env, 388 JNIEnv* env,
387 const net::SpdyHeaderBlock& header_block) { 389 const net::SpdyHeaderBlock& header_block) {
388 DCHECK(context_->IsOnNetworkThread()); 390 DCHECK(context_->IsOnNetworkThread());
389 391
390 std::vector<std::string> headers; 392 std::vector<std::string> headers;
391 for (const auto& header : header_block) { 393 for (const auto& header : header_block) {
392 headers.push_back(header.first.as_string()); 394 headers.push_back(header.first.as_string());
393 headers.push_back(header.second.as_string()); 395 headers.push_back(header.second.as_string());
394 } 396 }
395 return base::android::ToJavaArrayOfStrings(env, headers); 397 return base::android::ToJavaArrayOfStrings(env, headers);
396 } 398 }
397 399
398 } // namespace cronet 400 } // namespace cronet
OLDNEW
« no previous file with comments | « components/cronet/android/cronet_bidirectional_stream_adapter.h ('k') | net/http/bidirectional_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698