26
26
#include <aws/io/socket.h>
27
27
#include <aws/io/tls_channel_handler.h>
28
28
29
- #include <aws/common/atomics.h>
30
29
#include <aws/common/hash_table.h>
31
30
#include <aws/common/linked_list.h>
32
31
#include <aws/common/mutex.h>
@@ -39,7 +38,8 @@ static struct aws_http_connection_manager_system_vtable s_default_system_vtable
39
38
.create_connection = aws_http_client_connect ,
40
39
.release_connection = aws_http_connection_release ,
41
40
.close_connection = aws_http_connection_close ,
42
- .is_connection_open = aws_http_connection_is_open };
41
+ .is_connection_open = aws_http_connection_is_open ,
42
+ };
43
43
44
44
const struct aws_http_connection_manager_system_vtable * g_aws_http_connection_manager_default_system_vtable_ptr =
45
45
& s_default_system_vtable ;
@@ -310,14 +310,47 @@ static bool s_aws_http_connection_manager_should_destroy(struct aws_http_connect
310
310
* simply by setting the error_code and moving it to the current transaction's completion list.
311
311
*/
312
312
struct aws_http_connection_acquisition {
313
+ struct aws_allocator * allocator ;
313
314
struct aws_linked_list_node node ;
314
315
struct aws_http_connection_manager * manager ; /* Only used by logging */
315
316
aws_http_connection_manager_on_connection_setup_fn * callback ;
316
317
void * user_data ;
317
318
struct aws_http_connection * connection ;
318
319
int error_code ;
320
+ struct aws_channel_task acquisition_task ;
319
321
};
320
322
323
+ static void s_connection_acquisition_task (
324
+ struct aws_channel_task * channel_task ,
325
+ void * arg ,
326
+ enum aws_task_status status ) {
327
+ (void )channel_task ;
328
+
329
+ struct aws_http_connection_acquisition * pending_acquisition = arg ;
330
+
331
+ /* this is a channel task. If it is canceled, that means the channel shutdown. In that case, that's equivalent
332
+ * to a closed connection. */
333
+ if (status != AWS_TASK_STATUS_RUN_READY ) {
334
+ AWS_LOGF_WARN (
335
+ AWS_LS_HTTP_CONNECTION_MANAGER ,
336
+ "id=%p: Failed to complete connection acquisition because the connection was closed" ,
337
+ (void * )pending_acquisition -> manager );
338
+ pending_acquisition -> callback (NULL , AWS_ERROR_HTTP_CONNECTION_CLOSED , pending_acquisition -> user_data );
339
+ /* release it back to prevent a leak of the connection count. */
340
+ aws_http_connection_manager_release_connection (pending_acquisition -> manager , pending_acquisition -> connection );
341
+ } else {
342
+ AWS_LOGF_DEBUG (
343
+ AWS_LS_HTTP_CONNECTION_MANAGER ,
344
+ "id=%p: Successfully completed connection acquisition with connection id=%p" ,
345
+ (void * )pending_acquisition -> manager ,
346
+ (void * )pending_acquisition -> connection );
347
+ pending_acquisition -> callback (
348
+ pending_acquisition -> connection , pending_acquisition -> error_code , pending_acquisition -> user_data );
349
+ }
350
+
351
+ aws_mem_release (pending_acquisition -> allocator , pending_acquisition );
352
+ }
353
+
321
354
/*
322
355
* Invokes a set of connection acquisition completion callbacks.
323
356
*
@@ -335,24 +368,38 @@ static void s_aws_http_connection_manager_complete_acquisitions(
335
368
struct aws_http_connection_acquisition * pending_acquisition =
336
369
AWS_CONTAINER_OF (node , struct aws_http_connection_acquisition , node );
337
370
338
- pending_acquisition -> callback (
339
- pending_acquisition -> connection , pending_acquisition -> error_code , pending_acquisition -> user_data );
371
+ if (pending_acquisition -> error_code == AWS_OP_SUCCESS ) {
372
+ struct aws_channel * channel = aws_http_connection_get_channel (pending_acquisition -> connection );
373
+ AWS_PRECONDITION (channel );
374
+
375
+ /* For some workloads, going ahead and moving the connection callback to the connection's thread is a
376
+ * substantial performance improvement so let's do that */
377
+ if (!aws_channel_thread_is_callers_thread (channel )) {
378
+ aws_channel_task_init (
379
+ & pending_acquisition -> acquisition_task ,
380
+ s_connection_acquisition_task ,
381
+ pending_acquisition ,
382
+ "s_connection_acquisition_task" );
383
+ aws_channel_schedule_task_now (channel , & pending_acquisition -> acquisition_task );
384
+ return ;
385
+ }
386
+ AWS_LOGF_DEBUG (
387
+ AWS_LS_HTTP_CONNECTION_MANAGER ,
388
+ "id=%p: Successfully completed connection acquisition with connection id=%p" ,
389
+ (void * )pending_acquisition -> manager ,
390
+ (void * )pending_acquisition -> connection );
340
391
341
- if ( pending_acquisition -> error_code != 0 ) {
392
+ } else {
342
393
AWS_LOGF_WARN (
343
394
AWS_LS_HTTP_CONNECTION_MANAGER ,
344
- "id=%p: Failed to completed connection acquisition with error_code %d(%s)" ,
395
+ "id=%p: Failed to complete connection acquisition with error_code %d(%s)" ,
345
396
(void * )pending_acquisition -> manager ,
346
397
pending_acquisition -> error_code ,
347
398
aws_error_str (pending_acquisition -> error_code ));
348
- } else {
349
- AWS_LOGF_DEBUG (
350
- AWS_LS_HTTP_CONNECTION_MANAGER ,
351
- "id=%p: Successfully completed connection acquisition with connection id=%p" ,
352
- (void * )pending_acquisition -> manager ,
353
- (void * )pending_acquisition -> connection );
354
399
}
355
400
401
+ pending_acquisition -> callback (
402
+ pending_acquisition -> connection , pending_acquisition -> error_code , pending_acquisition -> user_data );
356
403
aws_mem_release (allocator , pending_acquisition );
357
404
}
358
405
}
@@ -856,6 +903,7 @@ void aws_http_connection_manager_acquire_connection(
856
903
return ;
857
904
}
858
905
906
+ request -> allocator = manager -> allocator ;
859
907
request -> callback = callback ;
860
908
request -> user_data = user_data ;
861
909
0 commit comments