@@ -465,18 +465,23 @@ static void s_client_bootstrap_on_channel_setup(
465
465
AWS_ASSERT (user_data );
466
466
struct aws_http_client_bootstrap * http_bootstrap = user_data ;
467
467
468
+ /* Contract for setup callbacks is: channel is NULL if error_code is non-zero. */
469
+ AWS_FATAL_ASSERT ((error_code != 0 ) == (channel == NULL ));
470
+
468
471
if (error_code ) {
469
472
AWS_LOGF_ERROR (
470
473
AWS_LS_HTTP_CONNECTION ,
471
474
"static: Client connection failed with error %d (%s)." ,
472
475
error_code ,
473
476
aws_error_name (error_code ));
474
- goto error ;
475
- }
476
477
477
- if (!channel ) {
478
- AWS_LOGF_ERROR (AWS_LS_HTTP_CONNECTION , "static: Client connection did not produce a channel" );
479
- goto error ;
478
+ /* Immediately tell user of failed connection.
479
+ * No channel exists, so there will be no channel_shutdown callback. */
480
+ http_bootstrap -> on_setup (NULL , error_code , http_bootstrap -> user_data );
481
+
482
+ /* Clean up the http_bootstrap, it has no more work to do. */
483
+ aws_mem_release (http_bootstrap -> alloc , http_bootstrap );
484
+ return ;
480
485
}
481
486
482
487
AWS_LOGF_TRACE (AWS_LS_HTTP_CONNECTION , "static: Socket connected, creating client connection object." );
@@ -499,31 +504,20 @@ static void s_client_bootstrap_on_channel_setup(
499
504
(void * )http_bootstrap -> connection ,
500
505
AWS_BYTE_CURSOR_PRI (aws_http_version_to_str (http_bootstrap -> connection -> http_version )));
501
506
502
- /* Tell user of successful connection. */
507
+ /* Tell user of successful connection.
508
+ * Then clear the on_setup callback so that we know it's been called */
503
509
http_bootstrap -> on_setup (http_bootstrap -> connection , AWS_ERROR_SUCCESS , http_bootstrap -> user_data );
510
+ http_bootstrap -> on_setup = NULL ;
511
+
504
512
return ;
505
513
506
514
error :
507
- if (!error_code ) {
508
- error_code = aws_last_error ();
509
- }
510
-
511
- /* Tell user of failed connection */
512
- http_bootstrap -> on_setup (NULL , error_code , http_bootstrap -> user_data );
513
-
514
- /* on_shutdown isn't allowed to be called if on_setup reports an error */
515
- http_bootstrap -> on_shutdown = NULL ;
516
-
517
- if (channel ) {
518
- /* If channel exists, invoke shutdown. http_bootstrap must stay alive until channel shutdown completes. */
519
- aws_channel_shutdown (channel , error_code );
520
- } else {
521
- /* If channel does not exist, clean up the http_bootstrap. It has no more work to do. */
522
- aws_mem_release (http_bootstrap -> alloc , http_bootstrap );
523
- }
515
+ /* Something went wrong. Invoke channel shutdown. Then wait for channel shutdown to complete
516
+ * before informing the user that setup failed and cleaning up the http_bootstrap.*/
517
+ aws_channel_shutdown (channel , aws_last_error ());
524
518
}
525
519
526
- /* At this point, the channel for a client connection has complete shutdown, but hasn't been destroyed yet. */
520
+ /* At this point, the channel for a client connection has completed its shutdown */
527
521
static void s_client_bootstrap_on_channel_shutdown (
528
522
struct aws_client_bootstrap * channel_bootstrap ,
529
523
int error_code ,
@@ -536,8 +530,30 @@ static void s_client_bootstrap_on_channel_shutdown(
536
530
AWS_ASSERT (user_data );
537
531
struct aws_http_client_bootstrap * http_bootstrap = user_data ;
538
532
539
- /* Tell user about shutdown */
540
- if (http_bootstrap -> on_shutdown ) {
533
+ /* If on_setup hasn't been called yet, inform user of failed setup.
534
+ * If on_setup was already called, inform user that it's shut down now. */
535
+ if (http_bootstrap -> on_setup ) {
536
+ /* make super duper sure that failed setup receives a non-zero error_code */
537
+ if (error_code == 0 ) {
538
+ error_code = AWS_ERROR_UNKNOWN ;
539
+ }
540
+
541
+ AWS_LOGF_ERROR (
542
+ AWS_LS_HTTP_CONNECTION ,
543
+ "static: Client setup failed with error %d (%s)." ,
544
+ error_code ,
545
+ aws_error_name (error_code ));
546
+
547
+ http_bootstrap -> on_setup (NULL , error_code , http_bootstrap -> user_data );
548
+
549
+ } else if (http_bootstrap -> on_shutdown ) {
550
+ AWS_LOGF_ERROR (
551
+ AWS_LS_HTTP_CONNECTION ,
552
+ "%p: Client shutdown completed with error %d (%s)." ,
553
+ (void * )http_bootstrap -> connection ,
554
+ error_code ,
555
+ aws_error_name (error_code ));
556
+
541
557
http_bootstrap -> on_shutdown (http_bootstrap -> connection , error_code , http_bootstrap -> user_data );
542
558
}
543
559
0 commit comments