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
 	.close		= downloader_xfer_close,
228
 	.close		= downloader_xfer_close,
229
 	.vredirect	= xfer_vopen,
229
 	.vredirect	= xfer_vopen,
230
 	.seek		= downloader_xfer_seek,
230
 	.seek		= downloader_xfer_seek,
231
+	.window		= unlimited_xfer_window,
231
 	.deliver_iob	= xfer_deliver_as_raw,
232
 	.deliver_iob	= xfer_deliver_as_raw,
232
 	.deliver_raw	= downloader_xfer_deliver_raw,
233
 	.deliver_raw	= downloader_xfer_deliver_raw,
233
 };
234
 };

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

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

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

160
 	.close		= posix_file_xfer_close,
160
 	.close		= posix_file_xfer_close,
161
 	.vredirect	= xfer_vopen,
161
 	.vredirect	= xfer_vopen,
162
 	.seek		= posix_file_xfer_seek,
162
 	.seek		= posix_file_xfer_seek,
163
+	.window		= unlimited_xfer_window,
163
 	.alloc_iob	= default_xfer_alloc_iob,
164
 	.alloc_iob	= default_xfer_alloc_iob,
164
 	.deliver_iob	= posix_file_xfer_deliver_iob,
165
 	.deliver_iob	= posix_file_xfer_deliver_iob,
165
 	.deliver_raw	= xfer_deliver_as_iob,
166
 	.deliver_raw	= xfer_deliver_as_iob,

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

308
 	int have_local;
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
 /** Named socket opener data transfer interface operations */
311
 /** Named socket opener data transfer interface operations */
326
 static struct xfer_interface_operations named_xfer_ops = {
312
 static struct xfer_interface_operations named_xfer_ops = {
327
 	.close		= ignore_xfer_close,
313
 	.close		= ignore_xfer_close,
328
 	.vredirect	= ignore_xfer_vredirect,
314
 	.vredirect	= ignore_xfer_vredirect,
329
-	.seek		= resolv_xfer_seek,
315
+	.seek		= ignore_xfer_seek,
316
+	.window		= no_xfer_window,
330
 	.alloc_iob	= default_xfer_alloc_iob,
317
 	.alloc_iob	= default_xfer_alloc_iob,
331
 	.deliver_iob	= xfer_deliver_as_raw,
318
 	.deliver_iob	= xfer_deliver_as_raw,
332
 	.deliver_raw	= ignore_xfer_deliver_raw,
319
 	.deliver_raw	= ignore_xfer_deliver_raw,

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

110
 	return rc;
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
  * Test to see if interface is ready to accept data
130
  * Test to see if interface is ready to accept data
115
  *
131
  *
297
 	return 0;
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
  * Allocate I/O buffer
343
  * Allocate I/O buffer
302
  *
344
  *
374
 	.close		= ignore_xfer_close,
416
 	.close		= ignore_xfer_close,
375
 	.vredirect	= ignore_xfer_vredirect,
417
 	.vredirect	= ignore_xfer_vredirect,
376
 	.seek		= ignore_xfer_seek,
418
 	.seek		= ignore_xfer_seek,
419
+	.window		= unlimited_xfer_window,
377
 	.alloc_iob	= default_xfer_alloc_iob,
420
 	.alloc_iob	= default_xfer_alloc_iob,
378
 	.deliver_iob	= xfer_deliver_as_raw,
421
 	.deliver_iob	= xfer_deliver_as_raw,
379
 	.deliver_raw	= ignore_xfer_deliver_raw,
422
 	.deliver_raw	= ignore_xfer_deliver_raw,

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

39
 	 * @v whence		Basis for new position
39
 	 * @v whence		Basis for new position
40
 	 * @ret rc		Return status code
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
 	int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
44
 	int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
48
 			 int whence );
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
 	/** Allocate I/O buffer
62
 	/** Allocate I/O buffer
50
 	 *
63
 	 *
51
 	 * @v xfer		Data transfer interface
64
 	 * @v xfer		Data transfer interface
64
 	 * A data transfer interface that wishes to support only raw
77
 	 * A data transfer interface that wishes to support only raw
65
 	 * data delivery should set this method to
78
 	 * data delivery should set this method to
66
 	 * xfer_deliver_as_raw().
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
 	int ( * deliver_iob ) ( struct xfer_interface *xfer,
81
 	int ( * deliver_iob ) ( struct xfer_interface *xfer,
73
 				struct io_buffer *iobuf,
82
 				struct io_buffer *iobuf,
82
 	 * A data transfer interface that wishes to support only I/O
91
 	 * A data transfer interface that wishes to support only I/O
83
 	 * buffer delivery should set this method to
92
 	 * buffer delivery should set this method to
84
 	 * xfer_deliver_as_iob().
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
 	int ( * deliver_raw ) ( struct xfer_interface *xfer,
95
 	int ( * deliver_raw ) ( struct xfer_interface *xfer,
91
 				const void *data, size_t len );
96
 				const void *data, size_t len );
137
 			    va_list args );
142
 			    va_list args );
138
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
143
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
139
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
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
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
146
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
142
 					   size_t len );
147
 					   size_t len );
143
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
148
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
157
 				   int type, va_list args );
162
 				   int type, va_list args );
158
 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
163
 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
159
 			      int whence );
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
 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
167
 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
161
 						   size_t len );
168
 						   size_t len );
162
 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
169
 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,

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

104
 	.close		= ignore_xfer_close,
104
 	.close		= ignore_xfer_close,
105
 	.vredirect	= ignore_xfer_vredirect,
105
 	.vredirect	= ignore_xfer_vredirect,
106
 	.seek		= ignore_xfer_seek,
106
 	.seek		= ignore_xfer_seek,
107
+	.window		= unlimited_xfer_window,
107
 	.alloc_iob	= default_xfer_alloc_iob,
108
 	.alloc_iob	= default_xfer_alloc_iob,
108
 	.deliver_iob	= pxe_udp_deliver_iob,
109
 	.deliver_iob	= pxe_udp_deliver_iob,
109
 	.deliver_raw	= xfer_deliver_as_iob,
110
 	.deliver_raw	= xfer_deliver_as_iob,

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

897
 }
897
 }
898
 
898
 
899
 /**
899
 /**
900
- * Seek to position
900
+ * Check flow control window
901
  *
901
  *
902
  * @v xfer		Data transfer interface
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
 	struct tcp_connection *tcp =
906
 	struct tcp_connection *tcp =
910
 		container_of ( xfer, struct tcp_connection, xfer );
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
 	/* Not ready if we're not in a suitable connection state */
909
 	/* Not ready if we're not in a suitable connection state */
917
 	if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
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
 	if ( ! list_empty ( &tcp->queue ) )
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
 static struct xfer_interface_operations tcp_xfer_operations = {
948
 static struct xfer_interface_operations tcp_xfer_operations = {
952
 	.close		= tcp_xfer_close,
949
 	.close		= tcp_xfer_close,
953
 	.vredirect	= ignore_xfer_vredirect,
950
 	.vredirect	= ignore_xfer_vredirect,
954
-	.seek		= tcp_xfer_seek,
951
+	.seek		= ignore_xfer_seek,
952
+	.window		= tcp_xfer_window,
955
 	.alloc_iob	= default_xfer_alloc_iob,
953
 	.alloc_iob	= default_xfer_alloc_iob,
956
 	.deliver_iob	= tcp_xfer_deliver_iob,
954
 	.deliver_iob	= tcp_xfer_deliver_iob,
957
 	.deliver_raw	= xfer_deliver_as_iob,
955
 	.deliver_raw	= xfer_deliver_as_iob,

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

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

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

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

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

415
 	.close		= udp_xfer_close,
415
 	.close		= udp_xfer_close,
416
 	.vredirect	= ignore_xfer_vredirect,
416
 	.vredirect	= ignore_xfer_vredirect,
417
 	.seek		= ignore_xfer_seek,
417
 	.seek		= ignore_xfer_seek,
418
+	.window		= unlimited_xfer_window,
418
 	.alloc_iob	= udp_alloc_iob,
419
 	.alloc_iob	= udp_alloc_iob,
419
 	.deliver_iob	= udp_xfer_deliver_iob,
420
 	.deliver_iob	= udp_xfer_deliver_iob,
420
 	.deliver_raw	= xfer_deliver_as_iob,
421
 	.deliver_raw	= xfer_deliver_as_iob,

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

722
 	.close		= ignore_xfer_close,
722
 	.close		= ignore_xfer_close,
723
 	.vredirect	= xfer_vopen,
723
 	.vredirect	= xfer_vopen,
724
 	.seek		= ignore_xfer_seek,
724
 	.seek		= ignore_xfer_seek,
725
+	.window		= unlimited_xfer_window,
725
 	.deliver_iob	= xfer_deliver_as_raw,
726
 	.deliver_iob	= xfer_deliver_as_raw,
726
 	.deliver_raw	= dhcp_deliver_raw,
727
 	.deliver_raw	= dhcp_deliver_raw,
727
 };
728
 };

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

433
 	.close		= dns_xfer_close,
433
 	.close		= dns_xfer_close,
434
 	.vredirect	= xfer_vopen,
434
 	.vredirect	= xfer_vopen,
435
 	.seek		= ignore_xfer_seek,
435
 	.seek		= ignore_xfer_seek,
436
+	.window		= unlimited_xfer_window,
436
 	.alloc_iob	= default_xfer_alloc_iob,
437
 	.alloc_iob	= default_xfer_alloc_iob,
437
 	.deliver_iob	= xfer_deliver_as_raw,
438
 	.deliver_iob	= xfer_deliver_as_raw,
438
 	.deliver_raw	= dns_xfer_deliver_raw,
439
 	.deliver_raw	= dns_xfer_deliver_raw,

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

583
 	.close		= tftp_socket_close,
583
 	.close		= tftp_socket_close,
584
 	.vredirect	= xfer_vopen,
584
 	.vredirect	= xfer_vopen,
585
 	.seek		= ignore_xfer_seek,
585
 	.seek		= ignore_xfer_seek,
586
+	.window		= unlimited_xfer_window,
586
 	.alloc_iob	= default_xfer_alloc_iob,
587
 	.alloc_iob	= default_xfer_alloc_iob,
587
 	.deliver_iob	= tftp_socket_deliver_iob,
588
 	.deliver_iob	= tftp_socket_deliver_iob,
588
 	.deliver_raw	= xfer_deliver_as_iob,
589
 	.deliver_raw	= xfer_deliver_as_iob,
609
 	.close		= tftp_xfer_close,
610
 	.close		= tftp_xfer_close,
610
 	.vredirect	= ignore_xfer_vredirect,
611
 	.vredirect	= ignore_xfer_vredirect,
611
 	.seek		= ignore_xfer_seek,
612
 	.seek		= ignore_xfer_seek,
613
+	.window		= unlimited_xfer_window,
612
 	.alloc_iob	= default_xfer_alloc_iob,
614
 	.alloc_iob	= default_xfer_alloc_iob,
613
 	.deliver_iob	= xfer_deliver_as_raw,
615
 	.deliver_iob	= xfer_deliver_as_raw,
614
 	.deliver_raw	= ignore_xfer_deliver_raw,
616
 	.deliver_raw	= ignore_xfer_deliver_raw,

Loading…
Cancel
Save