Browse Source

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 17 years ago
parent
commit
10d0a1f8c7
5 changed files with 96 additions and 41 deletions
  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 View File

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
  * Handle kill() event received via job control interface
118
  * Handle kill() event received via job control interface
132
  *
119
  *
142
 
129
 
143
 /** Downloader job control interface operations */
130
 /** Downloader job control interface operations */
144
 static struct job_interface_operations downloader_job_operations = {
131
 static struct job_interface_operations downloader_job_operations = {
145
-	.start		= downloader_job_start,
132
+	.start		= ignore_job_start,
146
 	.done		= ignore_job_done,
133
 	.done		= ignore_job_done,
147
 	.kill		= downloader_job_kill,
134
 	.kill		= downloader_job_kill,
148
 	.progress	= ignore_job_progress,
135
 	.progress	= ignore_job_progress,

+ 15
- 12
src/core/hw.c View File

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

+ 4
- 4
src/core/posix_io.c View File

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

+ 61
- 10
src/core/xfer.c View File

35
 void xfer_close ( struct xfer_interface *xfer, int rc ) {
35
 void xfer_close ( struct xfer_interface *xfer, int rc ) {
36
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
36
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
37
 
37
 
38
+	DBGC ( xfer, "XFER %p->%p close\n", xfer, dest );
39
+
38
 	dest->op->close ( dest, rc );
40
 	dest->op->close ( dest, rc );
39
 	xfer_unplug ( xfer );
41
 	xfer_unplug ( xfer );
40
 	xfer_put ( dest );
42
 	xfer_put ( dest );
52
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
54
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
53
 	int rc;
55
 	int rc;
54
 
56
 
57
+	DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest );
58
+
55
 	rc = dest->op->vredirect ( dest, type, args );
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
 	xfer_put ( dest );
65
 	xfer_put ( dest );
57
 	return rc;
66
 	return rc;
58
 }
67
 }
89
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
98
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
90
 	int rc;
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
 	rc = dest->op->request ( dest, offset, whence, len );
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
 	xfer_put ( dest );
110
 	xfer_put ( dest );
94
 	return rc;
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
  * Seek to position
115
  * Seek to position
109
  *
116
  *
116
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
123
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
117
 	int rc;
124
 	int rc;
118
 
125
 
126
+	DBGC ( xfer, "XFER %p->%p seek %s+%ld\n", xfer, dest,
127
+	       whence_text ( whence ), offset );
128
+
119
 	rc = dest->op->seek ( dest, offset, whence );
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
 	xfer_put ( dest );
135
 	xfer_put ( dest );
121
 	return rc;
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
  * Allocate I/O buffer
154
  * Allocate I/O buffer
126
  *
155
  *
132
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
161
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
133
 	struct io_buffer *iobuf;
162
 	struct io_buffer *iobuf;
134
 
163
 
164
+	DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len );
165
+
135
 	iobuf = dest->op->alloc_iob ( dest, len );
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
 	xfer_put ( dest );
171
 	xfer_put ( dest );
137
 	return iobuf;
172
 	return iobuf;
138
 }
173
 }
148
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
183
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
149
 	int rc;
184
 	int rc;
150
 
185
 
186
+	DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest,
187
+	       iob_len ( iobuf ) );
188
+
151
 	rc = dest->op->deliver_iob ( dest, iobuf );
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
 	xfer_put ( dest );
195
 	xfer_put ( dest );
153
 	return rc;
196
 	return rc;
154
 }
197
 }
165
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
208
 	struct xfer_interface *dest = xfer_get_dest ( xfer );
166
 	int rc;
209
 	int rc;
167
 
210
 
211
+	DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest,
212
+	       data, len );
213
+
168
 	rc = dest->op->deliver_raw ( dest, data, len );
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
 	xfer_put ( dest );
220
 	xfer_put ( dest );
170
 	return rc;
221
 	return rc;
171
 }
222
 }

+ 15
- 1
src/include/gpxe/xfer.h View File

112
 	SEEK_CUR,
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
 extern struct xfer_interface null_xfer;
129
 extern struct xfer_interface null_xfer;
116
 extern struct xfer_interface_operations null_xfer_ops;
130
 extern struct xfer_interface_operations null_xfer_ops;
117
 
131
 
121
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
135
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
122
 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
136
 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
123
 			  int whence, size_t len );
137
 			  int whence, size_t len );
124
-extern int xfer_request_all ( struct xfer_interface *xfer );
125
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
138
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
139
+extern int xfer_ready ( struct xfer_interface *xfer );
126
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
140
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
127
 					   size_t len );
141
 					   size_t len );
128
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
142
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,

Loading…
Cancel
Save