]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
Modify data-xfer semantics: it is no longer necessary to call one of
authorMichael Brown <mcb30@etherboot.org>
Sat, 26 May 2007 15:04:36 +0000 (15:04 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 26 May 2007 15:04:36 +0000 (15:04 +0000)
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.

src/core/downloader.c
src/core/hw.c
src/core/posix_io.c
src/core/xfer.c
src/include/gpxe/xfer.h

index 2f28bc95327f4675647f62f055acde930cc49adb..15ef962d30c0f7159a5ea7c5d3b5cddb97cd7791 100644 (file)
@@ -114,19 +114,6 @@ static int downloader_ensure_size ( struct downloader *downloader,
  *
  */
 
-/**
- * Handle start() event received via job control interface
- *
- * @v job              Downloader job control interface
- */
-static void downloader_job_start ( struct job_interface *job ) {
-       struct downloader *downloader = 
-               container_of ( job, struct downloader, job );
-
-       /* Start data transfer */
-       xfer_request_all ( &downloader->xfer );
-}
-
 /**
  * Handle kill() event received via job control interface
  *
@@ -142,7 +129,7 @@ static void downloader_job_kill ( struct job_interface *job ) {
 
 /** Downloader job control interface operations */
 static struct job_interface_operations downloader_job_operations = {
-       .start          = downloader_job_start,
+       .start          = ignore_job_start,
        .done           = ignore_job_done,
        .kill           = downloader_job_kill,
        .progress       = ignore_job_progress,
index 77b39ba1a36788eab720ebe04f90feedee7fec19..a3eb85007bf0330e7007ded43f4c56242ec26346 100644 (file)
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <errno.h>
 #include <gpxe/refcnt.h>
+#include <gpxe/process.h>
 #include <gpxe/xfer.h>
 #include <gpxe/open.h>
 
@@ -15,6 +16,7 @@
 struct hw {
        struct refcnt refcnt;
        struct xfer_interface xfer;
+       struct process process;
 };
 
 static const char hw_msg[] = "Hello world!\n";
@@ -22,6 +24,7 @@ static const char hw_msg[] = "Hello world!\n";
 static void hw_finished ( struct hw *hw, int rc ) {
        xfer_nullify ( &hw->xfer );
        xfer_close ( &hw->xfer, rc );
+       process_del ( &hw->process );
 }
 
 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 ) {
        hw_finished ( hw, rc );
 }
 
-static int hw_xfer_request ( struct xfer_interface *xfer,
-                            off_t start __unused, int whence __unused,
-                            size_t len __unused ) {
-       struct hw *hw = container_of ( xfer, struct hw, xfer );
-       int rc;
-
-       rc = xfer_deliver_raw ( xfer, hw_msg, sizeof ( hw_msg ) );
-       hw_finished ( hw, rc );
-       return 0;
-}
-
 static struct xfer_interface_operations hw_xfer_operations = {
        .close          = hw_xfer_close,
        .vredirect      = ignore_xfer_vredirect,
-       .request        = hw_xfer_request,
+       .request        = ignore_xfer_request,
        .seek           = ignore_xfer_seek,
        .deliver_iob    = xfer_deliver_as_raw,
        .deliver_raw    = ignore_xfer_deliver_raw,
 };
 
+static void hw_step ( struct process *process ) {
+       struct hw *hw = container_of ( process, struct hw, process );
+       int rc;
+
+       if ( xfer_ready ( &hw->xfer ) == 0 ) {
+               rc = xfer_deliver_raw ( &hw->xfer, hw_msg, sizeof ( hw_msg ) );
+               hw_finished ( hw, rc );
+       }
+}
+
 static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
        struct hw *hw;
 
@@ -59,6 +61,7 @@ static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
                return -ENOMEM;
        memset ( hw, 0, sizeof ( *hw ) );
        xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt );
+       process_init ( &hw->process, hw_step, &hw->refcnt );
 
        /* Attach parent interface, mortalise self, and return */
        xfer_plug_plug ( &hw->xfer, xfer );
index 6cefbf7b94d9bd387d8293ab4ac524f979b66c45..3b5660e4f9b0361fde7045980728039f64454a57 100644 (file)
@@ -191,6 +191,7 @@ static int posix_find_free_fd ( void ) {
                if ( ! posix_fd_to_file ( fd ) )
                        return fd;
        }
+       DBG ( "POSIX could not find free file descriptor\n" );
        return -ENFILE;
 }
 
@@ -226,13 +227,11 @@ int open ( const char *uri_string ) {
        if ( ( rc = xfer_open_uri ( &file->xfer, uri_string ) ) != 0 )
                goto err;
 
-       /* Request data */
-       if ( ( rc = xfer_request_all ( &file->xfer ) ) != 0 )
-               goto err;
-
        /* Wait for open to succeed or fail */
        while ( list_empty ( &file->data ) ) {
                step();
+               if ( file->rc == 0 )
+                       break;
                if ( file->rc != -EINPROGRESS ) {
                        rc = file->rc;
                        goto err;
@@ -241,6 +240,7 @@ int open ( const char *uri_string ) {
 
        /* Add to list of open files.  List takes reference ownership. */
        list_add ( &file->list, &posix_files );
+       DBG ( "POSIX opened %s as file %d\n", uri_string, fd );
        return fd;
 
  err:
index f2783f5bdf932c6022697126e57defb8af6dfe23..54377c7059219032db010e92c202cf45c13c3fef 100644 (file)
@@ -35,6 +35,8 @@
 void xfer_close ( struct xfer_interface *xfer, int rc ) {
        struct xfer_interface *dest = xfer_get_dest ( xfer );
 
+       DBGC ( xfer, "XFER %p->%p close\n", xfer, dest );
+
        dest->op->close ( dest, rc );
        xfer_unplug ( xfer );
        xfer_put ( dest );
@@ -52,7 +54,14 @@ int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        int rc;
 
+       DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest );
+
        rc = dest->op->vredirect ( dest, type, args );
+
+       if ( rc != 0 ) {
+               DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest,
+                      strerror ( rc ) );
+       }
        xfer_put ( dest );
        return rc;
 }
@@ -89,21 +98,19 @@ int xfer_request ( struct xfer_interface *xfer, off_t offset, int whence,
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        int rc;
 
+       DBGC ( xfer, "XFER %p->%p request %s+%ld %zd\n", xfer, dest,
+              whence_text ( whence ), offset, len );
+
        rc = dest->op->request ( dest, offset, whence, len );
+
+       if ( rc != 0 ) {
+               DBGC ( xfer, "XFER %p<-%p request: %s\n", xfer, dest,
+                      strerror ( rc ) );
+       }
        xfer_put ( dest );
        return rc;
 }
 
-/**
- * Request all data
- *
- * @v xfer             Data transfer interface
- * @ret rc             Return status code
- */
-int xfer_request_all ( struct xfer_interface *xfer ) {
-       return xfer_request ( xfer, 0, SEEK_SET, ~( ( size_t ) 0 ) );
-}
-
 /**
  * Seek to position
  *
@@ -116,11 +123,33 @@ int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        int rc;
 
+       DBGC ( xfer, "XFER %p->%p seek %s+%ld\n", xfer, dest,
+              whence_text ( whence ), offset );
+
        rc = dest->op->seek ( dest, offset, whence );
+
+       if ( rc != 0 ) {
+               DBGC ( xfer, "XFER %p<-%p seek: %s\n", xfer, dest,
+                      strerror ( rc ) );
+       }
        xfer_put ( dest );
        return rc;
 }
 
+/**
+ * Test to see if interface is ready to accept data
+ *
+ * @v xfer             Data transfer interface
+ * @ret rc             Return status code
+ *
+ * This test is optional; the data transfer interface may wish that it
+ * does not yet wish to accept data, but cannot prevent attempts to
+ * deliver data to it.
+ */
+int xfer_ready ( struct xfer_interface *xfer ) {
+       return xfer_seek ( xfer, 0, SEEK_CUR );
+}
+
 /**
  * Allocate I/O buffer
  *
@@ -132,7 +161,13 @@ struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        struct io_buffer *iobuf;
 
+       DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len );
+
        iobuf = dest->op->alloc_iob ( dest, len );
+
+       if ( ! iobuf ) {
+               DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest );
+       }
        xfer_put ( dest );
        return iobuf;
 }
@@ -148,7 +183,15 @@ int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        int rc;
 
+       DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest,
+              iob_len ( iobuf ) );
+
        rc = dest->op->deliver_iob ( dest, iobuf );
+
+       if ( rc != 0 ) {
+               DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest,
+                      strerror ( rc ) );
+       }
        xfer_put ( dest );
        return rc;
 }
@@ -165,7 +208,15 @@ int xfer_deliver_raw ( struct xfer_interface *xfer,
        struct xfer_interface *dest = xfer_get_dest ( xfer );
        int rc;
 
+       DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest,
+              data, len );
+
        rc = dest->op->deliver_raw ( dest, data, len );
+
+       if ( rc != 0 ) {
+               DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest,
+                      strerror ( rc ) );
+       }
        xfer_put ( dest );
        return rc;
 }
index 71b69dc51f0d1e527d7680204b85efee922a8fbe..e6c896c39a0e096fe6e46235a16b78fcb7c828b2 100644 (file)
@@ -112,6 +112,20 @@ enum seek_whence {
        SEEK_CUR,
 };
 
+/**
+ * Describe seek basis
+ *
+ * @v whence           Basis for new position
+ */
+static inline __attribute__ (( always_inline )) const char *
+whence_text ( int whence ) {
+       switch ( whence ) {
+       case SEEK_SET:  return "SET";
+       case SEEK_CUR:  return "CUR";
+       default:        return "INVALID";
+       }
+}
+
 extern struct xfer_interface null_xfer;
 extern struct xfer_interface_operations null_xfer_ops;
 
@@ -121,8 +135,8 @@ extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
                          int whence, size_t len );
-extern int xfer_request_all ( struct xfer_interface *xfer );
 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
+extern int xfer_ready ( struct xfer_interface *xfer );
 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
                                           size_t len );
 extern int xfer_deliver_iob ( struct xfer_interface *xfer,