Browse Source

Separate the "is data ready" function of xfer_seek() into an

xfer_window() function, which can return a scalar rather than a
boolean.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
b34d4d0449

+ 1
- 0
src/core/downloader.c View File

@@ -228,6 +228,7 @@ static struct xfer_interface_operations downloader_xfer_operations = {
228 228
 	.close		= downloader_xfer_close,
229 229
 	.vredirect	= xfer_vopen,
230 230
 	.seek		= downloader_xfer_seek,
231
+	.window		= unlimited_xfer_window,
231 232
 	.deliver_iob	= xfer_deliver_as_raw,
232 233
 	.deliver_raw	= downloader_xfer_deliver_raw,
233 234
 };

+ 2
- 1
src/core/hw.c View File

@@ -37,6 +37,7 @@ static struct xfer_interface_operations hw_xfer_operations = {
37 37
 	.close		= hw_xfer_close,
38 38
 	.vredirect	= ignore_xfer_vredirect,
39 39
 	.seek		= ignore_xfer_seek,
40
+	.window		= unlimited_xfer_window,
40 41
 	.deliver_iob	= xfer_deliver_as_raw,
41 42
 	.deliver_raw	= ignore_xfer_deliver_raw,
42 43
 };
@@ -45,7 +46,7 @@ static void hw_step ( struct process *process ) {
45 46
 	struct hw *hw = container_of ( process, struct hw, process );
46 47
 	int rc;
47 48
 
48
-	if ( xfer_ready ( &hw->xfer ) == 0 ) {
49
+	if ( xfer_window ( &hw->xfer ) ) {
49 50
 		rc = xfer_deliver_raw ( &hw->xfer, hw_msg, sizeof ( hw_msg ) );
50 51
 		hw_finished ( hw, rc );
51 52
 	}

+ 1
- 0
src/core/posix_io.c View File

@@ -160,6 +160,7 @@ static struct xfer_interface_operations posix_file_xfer_operations = {
160 160
 	.close		= posix_file_xfer_close,
161 161
 	.vredirect	= xfer_vopen,
162 162
 	.seek		= posix_file_xfer_seek,
163
+	.window		= unlimited_xfer_window,
163 164
 	.alloc_iob	= default_xfer_alloc_iob,
164 165
 	.deliver_iob	= posix_file_xfer_deliver_iob,
165 166
 	.deliver_raw	= xfer_deliver_as_iob,

+ 2
- 15
src/core/resolv.c View File

@@ -308,25 +308,12 @@ struct named_socket {
308 308
 	int have_local;
309 309
 };
310 310
 
311
-/**
312
- * Handle seek() event
313
- *
314
- * @v xfer		Data transfer interface
315
- * @v offset		Offset to new position
316
- * @v whence		Basis for new position
317
- * @ret rc		Return status code
318
- */
319
-static int resolv_xfer_seek ( struct xfer_interface *xfer __unused,
320
-			      off_t offset __unused, int whence __unused ) {
321
-	/* Never ready to accept data */
322
-	return -EAGAIN;
323
-}
324
-
325 311
 /** Named socket opener data transfer interface operations */
326 312
 static struct xfer_interface_operations named_xfer_ops = {
327 313
 	.close		= ignore_xfer_close,
328 314
 	.vredirect	= ignore_xfer_vredirect,
329
-	.seek		= resolv_xfer_seek,
315
+	.seek		= ignore_xfer_seek,
316
+	.window		= no_xfer_window,
330 317
 	.alloc_iob	= default_xfer_alloc_iob,
331 318
 	.deliver_iob	= xfer_deliver_as_raw,
332 319
 	.deliver_raw	= ignore_xfer_deliver_raw,

+ 43
- 0
src/core/xfer.c View File

@@ -110,6 +110,22 @@ int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
110 110
 	return rc;
111 111
 }
112 112
 
113
+/**
114
+ * Check flow control window
115
+ *
116
+ * @v xfer		Data transfer interface
117
+ * @ret len		Length of window
118
+ */
119
+size_t xfer_window ( struct xfer_interface *xfer ) {
120
+	struct xfer_interface *dest = xfer_get_dest ( xfer );
121
+	size_t len;
122
+
123
+	len = dest->op->window ( dest );
124
+
125
+	xfer_put ( dest );
126
+	return len;
127
+}
128
+
113 129
 /**
114 130
  * Test to see if interface is ready to accept data
115 131
  *
@@ -297,6 +313,32 @@ int ignore_xfer_seek ( struct xfer_interface *xfer __unused,
297 313
 	return 0;
298 314
 }
299 315
 
316
+/**
317
+ * Unlimited flow control window
318
+ *
319
+ * @v xfer		Data transfer interface
320
+ * @ret len		Length of window
321
+ *
322
+ * This handler indicates that the interface is always ready to accept
323
+ * data.
324
+ */
325
+size_t unlimited_xfer_window ( struct xfer_interface *xfer __unused ) {
326
+	return ~( ( size_t ) 0 );
327
+}
328
+
329
+/**
330
+ * No flow control window
331
+ *
332
+ * @v xfer		Data transfer interface
333
+ * @ret len		Length of window
334
+ *
335
+ * This handler indicates that the interface is never ready to accept
336
+ * data.
337
+ */
338
+size_t no_xfer_window ( struct xfer_interface *xfer __unused ) {
339
+	return 0;
340
+}
341
+
300 342
 /**
301 343
  * Allocate I/O buffer
302 344
  *
@@ -374,6 +416,7 @@ struct xfer_interface_operations null_xfer_ops = {
374 416
 	.close		= ignore_xfer_close,
375 417
 	.vredirect	= ignore_xfer_vredirect,
376 418
 	.seek		= ignore_xfer_seek,
419
+	.window		= unlimited_xfer_window,
377 420
 	.alloc_iob	= default_xfer_alloc_iob,
378 421
 	.deliver_iob	= xfer_deliver_as_raw,
379 422
 	.deliver_raw	= ignore_xfer_deliver_raw,

+ 20
- 13
src/include/gpxe/xfer.h View File

@@ -39,13 +39,26 @@ struct xfer_interface_operations {
39 39
 	 * @v whence		Basis for new position
40 40
 	 * @ret rc		Return status code
41 41
 	 *
42
-	 * @c whence must be one of @c SEEK_SET or @c SEEK_CUR.  A
43
-	 * successful return indicates that the interface is ready to
44
-	 * immediately accept datagrams; return -EAGAIN if this is not
45
-	 * the case.
42
+	 * @c whence must be one of @c SEEK_SET or @c SEEK_CUR.
46 43
 	 */
47 44
 	int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
48 45
 			 int whence );
46
+	/** Check flow control window
47
+	 *
48
+	 * @v xfer		Data transfer interface
49
+	 * @ret len		Length of window
50
+	 *
51
+	 * Flow control is regarded as advisory but not mandatory.
52
+	 * Users who have control over their own rate of data
53
+	 * generation should perform a flow control check before
54
+	 * generating new data.  Users who have no control (such as
55
+	 * NIC drivers or filter layers) are not obliged to check.
56
+	 *
57
+	 * Data transfer interfaces must be prepared to accept
58
+	 * datagrams even if they are advertising a window of zero
59
+	 * bytes.
60
+	 */
61
+	size_t ( * window ) ( struct xfer_interface *xfer );
49 62
 	/** Allocate I/O buffer
50 63
 	 *
51 64
 	 * @v xfer		Data transfer interface
@@ -64,10 +77,6 @@ struct xfer_interface_operations {
64 77
 	 * A data transfer interface that wishes to support only raw
65 78
 	 * data delivery should set this method to
66 79
 	 * xfer_deliver_as_raw().
67
-	 *
68
-	 * Interfaces may not temporarily refuse to accept data by
69
-	 * returning -EAGAIN; such a response may be treated as a
70
-	 * fatal error.
71 80
 	 */
72 81
 	int ( * deliver_iob ) ( struct xfer_interface *xfer,
73 82
 				struct io_buffer *iobuf,
@@ -82,10 +91,6 @@ struct xfer_interface_operations {
82 91
 	 * A data transfer interface that wishes to support only I/O
83 92
 	 * buffer delivery should set this method to
84 93
 	 * xfer_deliver_as_iob().
85
-	 *
86
-	 * Interfaces may not temporarily refuse to accept data by
87
-	 * returning -EAGAIN; such a response may be treated as a
88
-	 * fatal error.
89 94
 	 */
90 95
 	int ( * deliver_raw ) ( struct xfer_interface *xfer,
91 96
 				const void *data, size_t len );
@@ -137,7 +142,7 @@ extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
137 142
 			    va_list args );
138 143
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
139 144
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
140
-extern int xfer_ready ( struct xfer_interface *xfer );
145
+extern size_t xfer_window ( struct xfer_interface *xfer );
141 146
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
142 147
 					   size_t len );
143 148
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
@@ -157,6 +162,8 @@ extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
157 162
 				   int type, va_list args );
158 163
 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
159 164
 			      int whence );
165
+extern size_t unlimited_xfer_window ( struct xfer_interface *xfer );
166
+extern size_t no_xfer_window ( struct xfer_interface *xfer );
160 167
 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
161 168
 						   size_t len );
162 169
 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,

+ 1
- 0
src/interface/pxe/pxe_udp.c View File

@@ -104,6 +104,7 @@ static struct xfer_interface_operations pxe_udp_xfer_operations = {
104 104
 	.close		= ignore_xfer_close,
105 105
 	.vredirect	= ignore_xfer_vredirect,
106 106
 	.seek		= ignore_xfer_seek,
107
+	.window		= unlimited_xfer_window,
107 108
 	.alloc_iob	= default_xfer_alloc_iob,
108 109
 	.deliver_iob	= pxe_udp_deliver_iob,
109 110
 	.deliver_raw	= xfer_deliver_as_iob,

+ 13
- 15
src/net/tcp.c View File

@@ -897,31 +897,28 @@ static void tcp_xfer_close ( struct xfer_interface *xfer, int rc ) {
897 897
 }
898 898
 
899 899
 /**
900
- * Seek to position
900
+ * Check flow control window
901 901
  *
902 902
  * @v xfer		Data transfer interface
903
- * @v offset		Offset to new position
904
- * @v whence		Basis for new position
905
- * @ret rc		Return status code
903
+ * @ret len		Length of window
906 904
  */
907
-static int tcp_xfer_seek ( struct xfer_interface *xfer, off_t offset,
908
-			   int whence ) {
905
+static size_t tcp_xfer_window ( struct xfer_interface *xfer ) {
909 906
 	struct tcp_connection *tcp =
910 907
 		container_of ( xfer, struct tcp_connection, xfer );
911 908
 
912
-	/* TCP doesn't support seeking to arbitrary positions */
913
-	if ( ( whence != SEEK_CUR ) || ( offset != 0 ) )
914
-		return -EINVAL;
915
-
916 909
 	/* Not ready if we're not in a suitable connection state */
917 910
 	if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
918
-		return -EAGAIN;
911
+		return 0;
919 912
 
920
-	/* Not ready if data queue is non-empty */
913
+	/* Not ready if data queue is non-empty.  This imposes a limit
914
+	 * of only one unACKed packet in the TX queue at any time; we
915
+	 * do this to conserve memory usage.
916
+	 */
921 917
 	if ( ! list_empty ( &tcp->queue ) )
922
-		return -EAGAIN;
918
+		return 0;
923 919
 
924
-	return 0;
920
+	/* Return TCP window length */
921
+	return tcp->snd_win;
925 922
 }
926 923
 
927 924
 /**
@@ -951,7 +948,8 @@ static int tcp_xfer_deliver_iob ( struct xfer_interface *xfer,
951 948
 static struct xfer_interface_operations tcp_xfer_operations = {
952 949
 	.close		= tcp_xfer_close,
953 950
 	.vredirect	= ignore_xfer_vredirect,
954
-	.seek		= tcp_xfer_seek,
951
+	.seek		= ignore_xfer_seek,
952
+	.window		= tcp_xfer_window,
955 953
 	.alloc_iob	= default_xfer_alloc_iob,
956 954
 	.deliver_iob	= tcp_xfer_deliver_iob,
957 955
 	.deliver_raw	= xfer_deliver_as_iob,

+ 3
- 0
src/net/tcp/ftp.c View File

@@ -297,6 +297,7 @@ static struct xfer_interface_operations ftp_control_operations = {
297 297
 	.close		= ftp_control_close,
298 298
 	.vredirect	= xfer_vopen,
299 299
 	.seek		= ignore_xfer_seek,
300
+	.window		= unlimited_xfer_window,
300 301
 	.alloc_iob	= default_xfer_alloc_iob,
301 302
 	.deliver_iob	= xfer_deliver_as_raw,
302 303
 	.deliver_raw	= ftp_control_deliver_raw,
@@ -361,6 +362,7 @@ static struct xfer_interface_operations ftp_data_operations = {
361 362
 	.close		= ftp_data_closed,
362 363
 	.vredirect	= xfer_vopen,
363 364
 	.seek		= ignore_xfer_seek,
365
+	.window		= unlimited_xfer_window,
364 366
 	.alloc_iob	= default_xfer_alloc_iob,
365 367
 	.deliver_iob	= ftp_data_deliver_iob,
366 368
 	.deliver_raw	= xfer_deliver_as_iob,
@@ -393,6 +395,7 @@ static struct xfer_interface_operations ftp_xfer_operations = {
393 395
 	.close		= ftp_xfer_closed,
394 396
 	.vredirect	= ignore_xfer_vredirect,
395 397
 	.seek		= ignore_xfer_seek,
398
+	.window		= unlimited_xfer_window,
396 399
 	.alloc_iob	= default_xfer_alloc_iob,
397 400
 	.deliver_iob	= xfer_deliver_as_raw,
398 401
 	.deliver_raw	= ignore_xfer_deliver_raw,

+ 3
- 1
src/net/tcp/http.c View File

@@ -388,7 +388,7 @@ static void http_step ( struct process *process ) {
388 388
 	const char *query = http->uri->query;
389 389
 	int rc;
390 390
 
391
-	if ( xfer_ready ( &http->socket ) == 0 ) {
391
+	if ( xfer_window ( &http->socket ) ) {
392 392
 		process_del ( &http->process );
393 393
 		if ( ( rc = xfer_printf ( &http->socket,
394 394
 					  "GET %s%s%s HTTP/1.1\r\n"
@@ -425,6 +425,7 @@ static struct xfer_interface_operations http_socket_operations = {
425 425
 	.close		= http_socket_close,
426 426
 	.vredirect	= xfer_vopen,
427 427
 	.seek		= ignore_xfer_seek,
428
+	.window		= unlimited_xfer_window,
428 429
 	.alloc_iob	= default_xfer_alloc_iob,
429 430
 	.deliver_iob	= http_socket_deliver_iob,
430 431
 	.deliver_raw	= xfer_deliver_as_iob,
@@ -451,6 +452,7 @@ static struct xfer_interface_operations http_xfer_operations = {
451 452
 	.close		= http_xfer_close,
452 453
 	.vredirect	= ignore_xfer_vredirect,
453 454
 	.seek		= ignore_xfer_seek,
455
+	.window		= unlimited_xfer_window,
454 456
 	.alloc_iob	= default_xfer_alloc_iob,
455 457
 	.deliver_iob	= xfer_deliver_as_raw,
456 458
 	.deliver_raw	= ignore_xfer_deliver_raw,

+ 1
- 0
src/net/udp.c View File

@@ -415,6 +415,7 @@ static struct xfer_interface_operations udp_xfer_operations = {
415 415
 	.close		= udp_xfer_close,
416 416
 	.vredirect	= ignore_xfer_vredirect,
417 417
 	.seek		= ignore_xfer_seek,
418
+	.window		= unlimited_xfer_window,
418 419
 	.alloc_iob	= udp_alloc_iob,
419 420
 	.deliver_iob	= udp_xfer_deliver_iob,
420 421
 	.deliver_raw	= xfer_deliver_as_iob,

+ 1
- 0
src/net/udp/dhcp.c View File

@@ -722,6 +722,7 @@ static struct xfer_interface_operations dhcp_xfer_operations = {
722 722
 	.close		= ignore_xfer_close,
723 723
 	.vredirect	= xfer_vopen,
724 724
 	.seek		= ignore_xfer_seek,
725
+	.window		= unlimited_xfer_window,
725 726
 	.deliver_iob	= xfer_deliver_as_raw,
726 727
 	.deliver_raw	= dhcp_deliver_raw,
727 728
 };

+ 1
- 0
src/net/udp/dns.c View File

@@ -433,6 +433,7 @@ static struct xfer_interface_operations dns_socket_operations = {
433 433
 	.close		= dns_xfer_close,
434 434
 	.vredirect	= xfer_vopen,
435 435
 	.seek		= ignore_xfer_seek,
436
+	.window		= unlimited_xfer_window,
436 437
 	.alloc_iob	= default_xfer_alloc_iob,
437 438
 	.deliver_iob	= xfer_deliver_as_raw,
438 439
 	.deliver_raw	= dns_xfer_deliver_raw,

+ 2
- 0
src/net/udp/tftp.c View File

@@ -583,6 +583,7 @@ static struct xfer_interface_operations tftp_socket_operations = {
583 583
 	.close		= tftp_socket_close,
584 584
 	.vredirect	= xfer_vopen,
585 585
 	.seek		= ignore_xfer_seek,
586
+	.window		= unlimited_xfer_window,
586 587
 	.alloc_iob	= default_xfer_alloc_iob,
587 588
 	.deliver_iob	= tftp_socket_deliver_iob,
588 589
 	.deliver_raw	= xfer_deliver_as_iob,
@@ -609,6 +610,7 @@ static struct xfer_interface_operations tftp_xfer_operations = {
609 610
 	.close		= tftp_xfer_close,
610 611
 	.vredirect	= ignore_xfer_vredirect,
611 612
 	.seek		= ignore_xfer_seek,
613
+	.window		= unlimited_xfer_window,
612 614
 	.alloc_iob	= default_xfer_alloc_iob,
613 615
 	.deliver_iob	= xfer_deliver_as_raw,
614 616
 	.deliver_raw	= ignore_xfer_deliver_raw,

Loading…
Cancel
Save