Просмотр исходного кода

[http] Eliminate polling while waiting for window to open

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 лет назад
Родитель
Сommit
3ad1a1a60a
1 измененных файлов: 46 добавлений и 32 удалений
  1. 46
    32
      src/net/tcp/http.c

+ 46
- 32
src/net/tcp/http.c Просмотреть файл

@@ -48,6 +48,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
48 48
 
49 49
 FEATURE ( FEATURE_PROTOCOL, "HTTP", DHCP_EB_FEATURE_HTTP, 1 );
50 50
 
51
+/** HTTP transmission state */
52
+enum http_tx_state {
53
+	HTTP_TX_REQUEST = 0,
54
+	HTTP_TX_DONE,
55
+};
56
+
51 57
 /** HTTP receive state */
52 58
 enum http_rx_state {
53 59
 	HTTP_RX_RESPONSE = 0,
@@ -75,6 +81,8 @@ struct http_request {
75 81
 
76 82
 	/** TX process */
77 83
 	struct process process;
84
+	/** TX state */
85
+	enum http_tx_state tx_state;
78 86
 
79 87
 	/** HTTP response code */
80 88
 	unsigned int response;
@@ -498,49 +506,55 @@ static void http_step ( struct http_request *http ) {
498 506
 	int rc;
499 507
 	int request_len = unparse_uri ( NULL, 0, http->uri,
500 508
 					URI_PATH_BIT | URI_QUERY_BIT );
509
+	char request[ request_len + 1 /* NUL */ ];
501 510
 
502
-	if ( xfer_window ( &http->socket ) ) {
503
-		char request[request_len + 1];
511
+	/* Do nothing if we have already transmitted the request */
512
+	if ( http->tx_state != HTTP_TX_REQUEST )
513
+		return;
504 514
 
505
-		/* Construct path?query request */
506
-		unparse_uri ( request, sizeof ( request ), http->uri,
507
-			      URI_PATH_BIT | URI_QUERY_BIT );
515
+	/* Do nothing until socket is ready */
516
+	if ( ! xfer_window ( &http->socket ) )
517
+		return;
508 518
 
509
-		/* We want to execute only once */
510
-		process_del ( &http->process );
519
+	/* Construct path?query request */
520
+	unparse_uri ( request, sizeof ( request ), http->uri,
521
+		      URI_PATH_BIT | URI_QUERY_BIT );
511 522
 
512
-		/* Construct authorisation, if applicable */
513
-		if ( user ) {
514
-			/* Make "user:password" string from decoded fields */
515
-			snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ),
516
-				   "%s:%s", user, password );
523
+	/* Construct authorisation, if applicable */
524
+	if ( user ) {
525
+		/* Make "user:password" string from decoded fields */
526
+		snprintf ( ( ( char * ) user_pw ), sizeof ( user_pw ),
527
+			   "%s:%s", user, password );
517 528
 
518
-			/* Base64-encode the "user:password" string */
519
-			base64_encode ( user_pw, user_pw_len, user_pw_base64 );
520
-		}
529
+		/* Base64-encode the "user:password" string */
530
+		base64_encode ( user_pw, user_pw_len, user_pw_base64 );
531
+	}
521 532
 
522
-		/* Send GET request */
523
-		if ( ( rc = xfer_printf ( &http->socket,
524
-					  "GET %s%s HTTP/1.1\r\n"
525
-					  "User-Agent: iPXE/" VERSION "\r\n"
526
-					  "%s%s%s"
527
-					  "Host: %s\r\n"
528
-					  "\r\n",
529
-					  http->uri->path ? "" : "/",
530
-					  request,
531
-					  ( user ?
532
-					    "Authorization: Basic " : "" ),
533
-					  ( user ? user_pw_base64 : "" ),
534
-					  ( user ? "\r\n" : "" ),
535
-					  host ) ) != 0 ) {
536
-			http_done ( http, rc );
537
-		}
533
+	/* Mark request as transmitted */
534
+	http->tx_state = HTTP_TX_DONE;
535
+
536
+	/* Send GET request */
537
+	if ( ( rc = xfer_printf ( &http->socket,
538
+				  "GET %s%s HTTP/1.1\r\n"
539
+				  "User-Agent: iPXE/" VERSION "\r\n"
540
+				  "%s%s%s"
541
+				  "Host: %s\r\n"
542
+				  "\r\n",
543
+				  http->uri->path ? "" : "/",
544
+				  request,
545
+				  ( user ?
546
+				    "Authorization: Basic " : "" ),
547
+				  ( user ? user_pw_base64 : "" ),
548
+				  ( user ? "\r\n" : "" ),
549
+				  host ) ) != 0 ) {
550
+		http_done ( http, rc );
538 551
 	}
539 552
 }
540 553
 
541 554
 /** HTTP socket interface operations */
542 555
 static struct interface_operation http_socket_operations[] = {
543 556
 	INTF_OP ( xfer_deliver, struct http_request *, http_socket_deliver ),
557
+	INTF_OP ( xfer_window_changed, struct http_request *, http_step ),
544 558
 	INTF_OP ( intf_close, struct http_request *, http_done ),
545 559
 };
546 560
 
@@ -561,7 +575,7 @@ static struct interface_descriptor http_xfer_desc =
561 575
 
562 576
 /** HTTP process descriptor */
563 577
 static struct process_descriptor http_process_desc =
564
-	PROC_DESC ( struct http_request, process, http_step );
578
+	PROC_DESC_ONCE ( struct http_request, process, http_step );
565 579
 
566 580
 /**
567 581
  * Initiate an HTTP connection, with optional filter

Загрузка…
Отмена
Сохранить