Explorar el Código

Modify data-xfer semantics: it is no longer necessary to call one of

request(), seek() or deliver_xxx() in order to start the data flow.
Autonomous generators must be genuinely autonomous (having their own
process), or otherwise arrange to be called.  TCP does this by
starting the retry timer immediately.

Add some debugging statements.
tags/v0.9.3
Michael Brown hace 17 años
padre
commit
10d0a1f8c7
Se han modificado 5 ficheros con 96 adiciones y 41 borrados
  1. 1
    14
      src/core/downloader.c
  2. 15
    12
      src/core/hw.c
  3. 4
    4
      src/core/posix_io.c
  4. 61
    10
      src/core/xfer.c
  5. 15
    1
      src/include/gpxe/xfer.h

+ 1
- 14
src/core/downloader.c Ver fichero

@@ -114,19 +114,6 @@ static int downloader_ensure_size ( struct downloader *downloader,
114 114
  *
115 115
  */
116 116
 
117
-/**
118
- * Handle start() event received via job control interface
119
- *
120
- * @v job		Downloader job control interface
121
- */
122
-static void downloader_job_start ( struct job_interface *job ) {
123
-	struct downloader *downloader = 
124
-		container_of ( job, struct downloader, job );
125
-
126
-	/* Start data transfer */
127
-	xfer_request_all ( &downloader->xfer );
128
-}
129
-
130 117
 /**
131 118
  * Handle kill() event received via job control interface
132 119
  *
@@ -142,7 +129,7 @@ static void downloader_job_kill ( struct job_interface *job ) {
142 129
 
143 130
 /** Downloader job control interface operations */
144 131
 static struct job_interface_operations downloader_job_operations = {
145
-	.start		= downloader_job_start,
132
+	.start		= ignore_job_start,
146 133
 	.done		= ignore_job_done,
147 134
 	.kill		= downloader_job_kill,
148 135
 	.progress	= ignore_job_progress,

+ 15
- 12
src/core/hw.c Ver fichero

@@ -3,6 +3,7 @@
3 3
 #include <string.h>
4 4
 #include <errno.h>
5 5
 #include <gpxe/refcnt.h>
6
+#include <gpxe/process.h>
6 7
 #include <gpxe/xfer.h>
7 8
 #include <gpxe/open.h>
8 9
 
@@ -15,6 +16,7 @@
15 16
 struct hw {
16 17
 	struct refcnt refcnt;
17 18
 	struct xfer_interface xfer;
19
+	struct process process;
18 20
 };
19 21
 
20 22
 static const char hw_msg[] = "Hello world!\n";
@@ -22,6 +24,7 @@ static const char hw_msg[] = "Hello world!\n";
22 24
 static void hw_finished ( struct hw *hw, int rc ) {
23 25
 	xfer_nullify ( &hw->xfer );
24 26
 	xfer_close ( &hw->xfer, rc );
27
+	process_del ( &hw->process );
25 28
 }
26 29
 
27 30
 static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) {
@@ -30,26 +33,25 @@ static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) {
30 33
 	hw_finished ( hw, rc );
31 34
 }
32 35
 
33
-static int hw_xfer_request ( struct xfer_interface *xfer,
34
-			     off_t start __unused, int whence __unused,
35
-			     size_t len __unused ) {
36
-	struct hw *hw = container_of ( xfer, struct hw, xfer );
37
-	int rc;
38
-
39
-	rc = xfer_deliver_raw ( xfer, hw_msg, sizeof ( hw_msg ) );
40
-	hw_finished ( hw, rc );
41
-	return 0;
42
-}
43
-
44 36
 static struct xfer_interface_operations hw_xfer_operations = {
45 37
 	.close		= hw_xfer_close,
46 38
 	.vredirect	= ignore_xfer_vredirect,
47
-	.request	= hw_xfer_request,
39
+	.request	= ignore_xfer_request,
48 40
 	.seek		= ignore_xfer_seek,
49 41
 	.deliver_iob	= xfer_deliver_as_raw,
50 42
 	.deliver_raw	= ignore_xfer_deliver_raw,
51 43
 };
52 44
 
45
+static void hw_step ( struct process *process ) {
46
+	struct hw *hw = container_of ( process, struct hw, process );
47
+	int rc;
48
+
49
+	if ( xfer_ready ( &hw->xfer ) == 0 ) {
50
+		rc = xfer_deliver_raw ( &hw->xfer, hw_msg, sizeof ( hw_msg ) );
51
+		hw_finished ( hw, rc );
52
+	}
53
+}
54
+
53 55
 static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
54 56
 	struct hw *hw;
55 57
 
@@ -59,6 +61,7 @@ static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
59 61
 		return -ENOMEM;
60 62
 	memset ( hw, 0, sizeof ( *hw ) );
61 63
 	xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt );
64
+	process_init ( &hw->process, hw_step, &hw->refcnt );
62 65
 
63 66
 	/* Attach parent interface, mortalise self, and return */
64 67
 	xfer_plug_plug ( &hw->xfer, xfer );

+ 4
- 4
src/core/posix_io.c Ver fichero

@@ -191,6 +191,7 @@ static int posix_find_free_fd ( void ) {
191 191
 		if ( ! posix_fd_to_file ( fd ) )
192 192
 			return fd;
193 193
 	}
194
+	DBG ( "POSIX could not find free file descriptor\n" );
194 195
 	return -ENFILE;
195 196
 }
196 197
 
@@ -226,13 +227,11 @@ int open ( const char *uri_string ) {
226 227
 	if ( ( rc = xfer_open_uri ( &file->xfer, uri_string ) ) != 0 )
227 228
 		goto err;
228 229
 
229
-	/* Request data */
230
-	if ( ( rc = xfer_request_all ( &file->xfer ) ) != 0 )
231
-		goto err;
232
-
233 230
 	/* Wait for open to succeed or fail */
234 231
 	while ( list_empty ( &file->data ) ) {
235 232
 		step();
233
+		if ( file->rc == 0 )
234
+			break;
236 235
 		if ( file->rc != -EINPROGRESS ) {
237 236
 			rc = file->rc;
238 237
 			goto err;
@@ -241,6 +240,7 @@ int open ( const char *uri_string ) {
241 240
 
242 241
 	/* Add to list of open files.  List takes reference ownership. */
243 242
 	list_add ( &file->list, &posix_files );
243
+	DBG ( "POSIX opened %s as file %d\n", uri_string, fd );
244 244
 	return fd;
245 245
 
246 246
  err:

+ 61
- 10
src/core/xfer.c Ver fichero

@@ -35,6 +35,8 @@
35 35
 void xfer_close ( struct xfer_interface *xfer, int rc ) {
36 36
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
37 37
 
38
+	DBGC ( xfer, "XFER %p->%p close\n", xfer, dest );
39
+
38 40
 	dest->op->close ( dest, rc );
39 41
 	xfer_unplug ( xfer );
40 42
 	xfer_put ( dest );
@@ -52,7 +54,14 @@ int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
52 54
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
53 55
 	int rc;
54 56
 
57
+	DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest );
58
+
55 59
 	rc = dest->op->vredirect ( dest, type, args );
60
+
61
+	if ( rc != 0 ) {
62
+		DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest,
63
+		       strerror ( rc ) );
64
+	}
56 65
 	xfer_put ( dest );
57 66
 	return rc;
58 67
 }
@@ -89,21 +98,19 @@ int xfer_request ( struct xfer_interface *xfer, off_t offset, int whence,
89 98
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
90 99
 	int rc;
91 100
 
101
+	DBGC ( xfer, "XFER %p->%p request %s+%ld %zd\n", xfer, dest,
102
+	       whence_text ( whence ), offset, len );
103
+
92 104
 	rc = dest->op->request ( dest, offset, whence, len );
105
+
106
+	if ( rc != 0 ) {
107
+		DBGC ( xfer, "XFER %p<-%p request: %s\n", xfer, dest,
108
+		       strerror ( rc ) );
109
+	}
93 110
 	xfer_put ( dest );
94 111
 	return rc;
95 112
 }
96 113
 
97
-/**
98
- * Request all data
99
- *
100
- * @v xfer		Data transfer interface
101
- * @ret rc		Return status code
102
- */
103
-int xfer_request_all ( struct xfer_interface *xfer ) {
104
-	return xfer_request ( xfer, 0, SEEK_SET, ~( ( size_t ) 0 ) );
105
-}
106
-
107 114
 /**
108 115
  * Seek to position
109 116
  *
@@ -116,11 +123,33 @@ int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
116 123
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
117 124
 	int rc;
118 125
 
126
+	DBGC ( xfer, "XFER %p->%p seek %s+%ld\n", xfer, dest,
127
+	       whence_text ( whence ), offset );
128
+
119 129
 	rc = dest->op->seek ( dest, offset, whence );
130
+
131
+	if ( rc != 0 ) {
132
+		DBGC ( xfer, "XFER %p<-%p seek: %s\n", xfer, dest,
133
+		       strerror ( rc ) );
134
+	}
120 135
 	xfer_put ( dest );
121 136
 	return rc;
122 137
 }
123 138
 
139
+/**
140
+ * Test to see if interface is ready to accept data
141
+ *
142
+ * @v xfer		Data transfer interface
143
+ * @ret rc		Return status code
144
+ *
145
+ * This test is optional; the data transfer interface may wish that it
146
+ * does not yet wish to accept data, but cannot prevent attempts to
147
+ * deliver data to it.
148
+ */
149
+int xfer_ready ( struct xfer_interface *xfer ) {
150
+	return xfer_seek ( xfer, 0, SEEK_CUR );
151
+}
152
+
124 153
 /**
125 154
  * Allocate I/O buffer
126 155
  *
@@ -132,7 +161,13 @@ struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
132 161
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
133 162
 	struct io_buffer *iobuf;
134 163
 
164
+	DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len );
165
+
135 166
 	iobuf = dest->op->alloc_iob ( dest, len );
167
+
168
+	if ( ! iobuf ) {
169
+		DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest );
170
+	}
136 171
 	xfer_put ( dest );
137 172
 	return iobuf;
138 173
 }
@@ -148,7 +183,15 @@ int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
148 183
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
149 184
 	int rc;
150 185
 
186
+	DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest,
187
+	       iob_len ( iobuf ) );
188
+
151 189
 	rc = dest->op->deliver_iob ( dest, iobuf );
190
+
191
+	if ( rc != 0 ) {
192
+		DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest,
193
+		       strerror ( rc ) );
194
+	}
152 195
 	xfer_put ( dest );
153 196
 	return rc;
154 197
 }
@@ -165,7 +208,15 @@ int xfer_deliver_raw ( struct xfer_interface *xfer,
165 208
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
166 209
 	int rc;
167 210
 
211
+	DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest,
212
+	       data, len );
213
+
168 214
 	rc = dest->op->deliver_raw ( dest, data, len );
215
+
216
+	if ( rc != 0 ) {
217
+		DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest,
218
+		       strerror ( rc ) );
219
+	}
169 220
 	xfer_put ( dest );
170 221
 	return rc;
171 222
 }

+ 15
- 1
src/include/gpxe/xfer.h Ver fichero

@@ -112,6 +112,20 @@ enum seek_whence {
112 112
 	SEEK_CUR,
113 113
 };
114 114
 
115
+/**
116
+ * Describe seek basis
117
+ *
118
+ * @v whence		Basis for new position
119
+ */
120
+static inline __attribute__ (( always_inline )) const char *
121
+whence_text ( int whence ) {
122
+	switch ( whence ) {
123
+	case SEEK_SET:	return "SET";
124
+	case SEEK_CUR:	return "CUR";
125
+	default:	return "INVALID";
126
+	}
127
+}
128
+
115 129
 extern struct xfer_interface null_xfer;
116 130
 extern struct xfer_interface_operations null_xfer_ops;
117 131
 
@@ -121,8 +135,8 @@ extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
121 135
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
122 136
 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
123 137
 			  int whence, size_t len );
124
-extern int xfer_request_all ( struct xfer_interface *xfer );
125 138
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
139
+extern int xfer_ready ( struct xfer_interface *xfer );
126 140
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
127 141
 					   size_t len );
128 142
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,

Loading…
Cancelar
Guardar