diff options
-rw-r--r-- | src/core/downloader.c | 69 | ||||
-rw-r--r-- | src/core/job.c | 85 | ||||
-rw-r--r-- | src/core/monojob.c | 29 | ||||
-rw-r--r-- | src/include/ipxe/dhcp.h | 6 | ||||
-rw-r--r-- | src/include/ipxe/downloader.h | 4 | ||||
-rw-r--r-- | src/include/ipxe/job.h | 137 | ||||
-rw-r--r-- | src/include/ipxe/monojob.h | 5 | ||||
-rw-r--r-- | src/net/udp/dhcp.c | 46 |
8 files changed, 88 insertions, 293 deletions
diff --git a/src/core/downloader.c b/src/core/downloader.c index 5499ddab..de5ea458 100644 --- a/src/core/downloader.c +++ b/src/core/downloader.c @@ -41,7 +41,7 @@ struct downloader { struct refcnt refcnt; /** Job control interface */ - struct job_interface job; + struct interface job; /** Data transfer interface */ struct xfer_interface xfer; @@ -74,13 +74,14 @@ static void downloader_free ( struct refcnt *refcnt ) { */ static void downloader_finished ( struct downloader *downloader, int rc ) { - /* Block further incoming messages */ - job_nullify ( &downloader->job ); - xfer_nullify ( &downloader->xfer ); + /* Register image if download was successful */ + if ( rc == 0 ) + rc = downloader->register_image ( downloader->image ); - /* Free resources and close interfaces */ + /* Shut down interfaces */ + xfer_nullify ( &downloader->xfer ); xfer_close ( &downloader->xfer, rc ); - job_done ( &downloader->job, rc ); + intf_shutdown ( &downloader->job, rc ); } /** @@ -121,28 +122,13 @@ static int downloader_ensure_size ( struct downloader *downloader, */ /** - * Handle kill() event received via job control interface - * - * @v job Downloader job control interface - */ -static void downloader_job_kill ( struct job_interface *job ) { - struct downloader *downloader = - container_of ( job, struct downloader, job ); - - /* Terminate download */ - downloader_finished ( downloader, -ECANCELED ); -} - -/** * Report progress of download job * - * @v job Downloader job control interface + * @v downloader Downloader * @v progress Progress report to fill in */ -static void downloader_job_progress ( struct job_interface *job, - struct job_progress *progress ) { - struct downloader *downloader = - container_of ( job, struct downloader, job ); +static void downloader_progress ( struct downloader *downloader, + struct job_progress *progress ) { /* This is not entirely accurate, since downloaded data may * arrive out of order (e.g. with multicast protocols), but @@ -152,13 +138,6 @@ static void downloader_job_progress ( struct job_interface *job, progress->total = downloader->image->len; } -/** Downloader job control interface operations */ -static struct job_interface_operations downloader_job_operations = { - .done = ignore_job_done, - .kill = downloader_job_kill, - .progress = downloader_job_progress, -}; - /**************************************************************************** * * Data transfer interface @@ -215,10 +194,6 @@ static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) { struct downloader *downloader = container_of ( xfer, struct downloader, xfer ); - /* Register image if download was successful */ - if ( rc == 0 ) - rc = downloader->register_image ( downloader->image ); - /* Terminate download */ downloader_finished ( downloader, rc ); } @@ -235,6 +210,22 @@ static struct xfer_interface_operations downloader_xfer_operations = { /**************************************************************************** * + * Job control interface + * + */ + +/** Downloader job control interface operations */ +static struct interface_operation downloader_job_op[] = { + INTF_OP ( job_progress, struct downloader *, downloader_progress ), + INTF_OP ( intf_close, struct downloader *, downloader_finished ), +}; + +/** Downloader job control interface descriptor */ +static struct interface_descriptor downloader_job_desc = + INTF_DESC ( struct downloader, job, downloader_job_op ); + +/**************************************************************************** + * * Instantiator * */ @@ -253,7 +244,7 @@ static struct xfer_interface_operations downloader_xfer_operations = { * the specified image object. If the download is successful, the * image registration routine @c register_image() will be called. */ -int create_downloader ( struct job_interface *job, struct image *image, +int create_downloader ( struct interface *job, struct image *image, int ( * register_image ) ( struct image *image ), int type, ... ) { struct downloader *downloader; @@ -265,8 +256,8 @@ int create_downloader ( struct job_interface *job, struct image *image, if ( ! downloader ) return -ENOMEM; ref_init ( &downloader->refcnt, downloader_free ); - job_init ( &downloader->job, &downloader_job_operations, - &downloader->refcnt ); + intf_init ( &downloader->job, &downloader_job_desc, + &downloader->refcnt ); xfer_init ( &downloader->xfer, &downloader_xfer_operations, &downloader->refcnt ); downloader->image = image_get ( image ); @@ -278,7 +269,7 @@ int create_downloader ( struct job_interface *job, struct image *image, goto err; /* Attach parent interface, mortalise self, and return */ - job_plug_plug ( &downloader->job, job ); + intf_plug_plug ( &downloader->job, job ); ref_put ( &downloader->refcnt ); va_end ( args ); return 0; diff --git a/src/core/job.c b/src/core/job.c index ffc0057f..ac4e43e7 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -28,70 +28,27 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ -void job_done ( struct job_interface *job, int rc ) { - struct job_interface *dest = job_get_dest ( job ); - - job_unplug ( job ); - dest->op->done ( dest, rc ); - job_put ( dest ); -} - -void job_kill ( struct job_interface *job ) { - struct job_interface *dest = job_get_dest ( job ); - - job_unplug ( job ); - dest->op->kill ( dest ); - job_put ( dest ); -} - -void job_progress ( struct job_interface *job, - struct job_progress *progress ) { - struct job_interface *dest = job_get_dest ( job ); - - dest->op->progress ( dest, progress ); - job_put ( dest ); -} - -/**************************************************************************** - * - * Helper methods - * - * These functions are designed to be used as methods in the - * job_interface_operations table. - * - */ - -void ignore_job_done ( struct job_interface *job __unused, int rc __unused ) { - /* Nothing to do */ -} - -void ignore_job_kill ( struct job_interface *job __unused ) { - /* Nothing to do */ -} - -void ignore_job_progress ( struct job_interface *job __unused, - struct job_progress *progress ) { - memset ( progress, 0, sizeof ( *progress ) ); -} - -/** Null job control interface operations */ -struct job_interface_operations null_job_ops = { - .done = ignore_job_done, - .kill = ignore_job_kill, - .progress = ignore_job_progress, -}; - /** - * Null job control interface + * Get job progress * - * This is the interface to which job control interfaces are connected - * when unplugged. It will never generate messages, and will silently - * absorb all received messages. + * @v intf Object interface + * @v progress Progress data to fill in */ -struct job_interface null_job = { - .intf = { - .dest = &null_job.intf, - .refcnt = NULL, - }, - .op = &null_job_ops, -}; +void job_progress ( struct interface *intf, struct job_progress *progress ) { + struct interface *dest; + job_progress_TYPE ( void * ) *op = + intf_get_dest_op ( intf, job_progress, &dest ); + void *object = intf_object ( dest ); + + DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " job_progress\n", + INTF_INTF_DBG ( intf, dest ) ); + + if ( op ) { + op ( object, progress ); + } else { + /* Default is to mark progress as zero */ + memset ( progress, 0, sizeof ( *progress ) ); + } + + intf_put ( dest ); +} diff --git a/src/core/monojob.c b/src/core/monojob.c index cd255076..994edeb1 100644 --- a/src/core/monojob.c +++ b/src/core/monojob.c @@ -36,25 +36,19 @@ FILE_LICENCE ( GPL2_OR_LATER ); static int monojob_rc; -static void monojob_done ( struct job_interface *job __unused, int rc ) { +static void monojob_close ( struct interface *intf, int rc ) { monojob_rc = rc; + intf_restart ( intf, rc ); } -/** Single foreground job operations */ -static struct job_interface_operations monojob_operations = { - .done = monojob_done, - .kill = ignore_job_kill, - .progress = ignore_job_progress, +static struct interface_operation monojob_intf_op[] = { + INTF_OP ( intf_close, struct interface *, monojob_close ), }; -/** Single foreground job */ -struct job_interface monojob = { - .intf = { - .dest = &null_job.intf, - .refcnt = NULL, - }, - .op = &monojob_operations, -}; +static struct interface_descriptor monojob_intf_desc = + INTF_DESC_PURE ( monojob_intf_op ); + +struct interface monojob = INTF_INIT ( monojob_intf_desc ); /** * Wait for single foreground job to complete @@ -77,9 +71,8 @@ int monojob_wait ( const char *string ) { key = getchar(); switch ( key ) { case CTRL_C: - job_kill ( &monojob ); - rc = -ECANCELED; - goto done; + monojob_close ( &monojob, -ECANCELED ); + break; default: break; } @@ -92,8 +85,6 @@ int monojob_wait ( const char *string ) { } rc = monojob_rc; -done: - job_done ( &monojob, rc ); if ( rc ) { printf ( " %s\n", strerror ( rc ) ); } else { diff --git a/src/include/ipxe/dhcp.h b/src/include/ipxe/dhcp.h index bbbe73d2..d07da378 100644 --- a/src/include/ipxe/dhcp.h +++ b/src/include/ipxe/dhcp.h @@ -18,7 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/netdevice.h> #include <ipxe/uaccess.h> -struct job_interface; +struct interface; struct dhcp_options; struct dhcp_packet; @@ -622,8 +622,8 @@ extern int dhcp_create_request ( struct dhcp_packet *dhcppkt, struct net_device *netdev, unsigned int msgtype, struct in_addr ciaddr, void *data, size_t max_len ); -extern int start_dhcp ( struct job_interface *job, struct net_device *netdev ); -extern int start_pxebs ( struct job_interface *job, struct net_device *netdev, +extern int start_dhcp ( struct interface *job, struct net_device *netdev ); +extern int start_pxebs ( struct interface *job, struct net_device *netdev, unsigned int pxe_type ); /* In environments that can provide cached DHCP packets, this function diff --git a/src/include/ipxe/downloader.h b/src/include/ipxe/downloader.h index 023bf94f..3b6a9d66 100644 --- a/src/include/ipxe/downloader.h +++ b/src/include/ipxe/downloader.h @@ -9,10 +9,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); -struct job_interface; +struct interface; struct image; -extern int create_downloader ( struct job_interface *job, struct image *image, +extern int create_downloader ( struct interface *job, struct image *image, int ( * register_image ) ( struct image *image ), int type, ... ); diff --git a/src/include/ipxe/job.h b/src/include/ipxe/job.h index 870b2e83..c2232fc1 100644 --- a/src/include/ipxe/job.h +++ b/src/include/ipxe/job.h @@ -9,7 +9,6 @@ FILE_LICENCE ( GPL2_OR_LATER ); -#include <stddef.h> #include <ipxe/interface.h> /** Job progress */ @@ -31,139 +30,9 @@ struct job_progress { unsigned long total; }; -struct job_interface; - -/** Job control interface operations */ -struct job_interface_operations { - /** Job completed - * - * @v job Job control interface - * @v rc Overall job status code - */ - void ( * done ) ( struct job_interface *job, int rc ); - /** Abort job - * - * @v job Job control interface - */ - void ( * kill ) ( struct job_interface *job ); - /** Get job progress - * - * @v job Job control interface - * @v progress Progress data to fill in - */ - void ( * progress ) ( struct job_interface *job, - struct job_progress *progress ); -}; - -/** A job control interface */ -struct job_interface { - /** Generic object communication interface */ - struct interface intf; - /** Operations for received messages */ - struct job_interface_operations *op; -}; - -extern struct job_interface null_job; -extern struct job_interface_operations null_job_ops; - -extern void job_done ( struct job_interface *job, int rc ); -extern void job_kill ( struct job_interface *job ); -extern void job_progress ( struct job_interface *job, +extern void job_progress ( struct interface *intf, struct job_progress *progress ); - -extern void ignore_job_done ( struct job_interface *job, int rc ); -extern void ignore_job_kill ( struct job_interface *job ); -extern void ignore_job_progress ( struct job_interface *job, - struct job_progress *progress ); - -/** - * Initialise a job control interface - * - * @v job Job control interface - * @v op Job control interface operations - * @v refcnt Containing object reference counter, or NULL - */ -static inline void job_init ( struct job_interface *job, - struct job_interface_operations *op, - struct refcnt *refcnt ) { - job->intf.dest = &null_job.intf; - job->intf.refcnt = refcnt; - job->op = op; -} - -/** - * Get job control interface from generic object communication interface - * - * @v intf Generic object communication interface - * @ret job Job control interface - */ -static inline __attribute__ (( always_inline )) struct job_interface * -intf_to_job ( struct interface *intf ) { - return container_of ( intf, struct job_interface, intf ); -} - -/** - * Get reference to destination job control interface - * - * @v job Job control interface - * @ret dest Destination interface - */ -static inline __attribute__ (( always_inline )) struct job_interface * -job_get_dest ( struct job_interface *job ) { - return intf_to_job ( intf_get ( job->intf.dest ) ); -} - -/** - * Drop reference to job control interface - * - * @v job Job control interface - */ -static inline __attribute__ (( always_inline )) void -job_put ( struct job_interface *job ) { - intf_put ( &job->intf ); -} - -/** - * Plug a job control interface into a new destination interface - * - * @v job Job control interface - * @v dest New destination interface - */ -static inline void job_plug ( struct job_interface *job, - struct job_interface *dest ) { - intf_plug ( &job->intf, &dest->intf ); -} - -/** - * Plug two job control interfaces together - * - * @v a Job control interface A - * @v b Job control interface B - */ -static inline void job_plug_plug ( struct job_interface *a, - struct job_interface *b ) { - intf_plug_plug ( &a->intf, &b->intf ); -} - -/** - * Unplug a job control interface - * - * @v job Job control interface - */ -static inline void job_unplug ( struct job_interface *job ) { - intf_plug ( &job->intf, &null_job.intf ); -} - -/** - * Stop using a job control interface - * - * @v job Job control interface - * - * After calling this method, no further messages will be received via - * the interface. - */ -static inline void job_nullify ( struct job_interface *job ) { - job->op = &null_job_ops; -}; +#define job_progress_TYPE( object_type ) \ + typeof ( void ( object_type, struct job_progress *progress ) ) #endif /* _IPXE_JOB_H */ diff --git a/src/include/ipxe/monojob.h b/src/include/ipxe/monojob.h index b2f3dfde..3d8b31c0 100644 --- a/src/include/ipxe/monojob.h +++ b/src/include/ipxe/monojob.h @@ -9,9 +9,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); -struct job_interface; +struct interface; + +extern struct interface monojob; -extern struct job_interface monojob; extern int monojob_wait ( const char *string ); #endif /* _IPXE_MONOJOB_H */ diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index fff331f7..99198319 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -238,7 +238,7 @@ struct dhcp_session { /** Reference counter */ struct refcnt refcnt; /** Job control interface */ - struct job_interface job; + struct interface job; /** Data transfer interface */ struct xfer_interface xfer; @@ -294,16 +294,13 @@ static void dhcp_free ( struct refcnt *refcnt ) { */ static void dhcp_finished ( struct dhcp_session *dhcp, int rc ) { - /* Block futher incoming messages */ - job_nullify ( &dhcp->job ); - xfer_nullify ( &dhcp->xfer ); - /* Stop retry timer */ stop_timer ( &dhcp->timer ); - /* Free resources and close interfaces */ + /* Shut down interfaces */ + xfer_nullify ( &dhcp->xfer ); xfer_close ( &dhcp->xfer, rc ); - job_done ( &dhcp->job, rc ); + intf_shutdown ( &dhcp->job, rc ); } /** @@ -1366,26 +1363,15 @@ static void dhcp_timer_expired ( struct retry_timer *timer, int fail ) { * */ -/** - * Handle kill() event received via job control interface - * - * @v job DHCP job control interface - */ -static void dhcp_job_kill ( struct job_interface *job ) { - struct dhcp_session *dhcp = - container_of ( job, struct dhcp_session, job ); - - /* Terminate DHCP session */ - dhcp_finished ( dhcp, -ECANCELED ); -} - /** DHCP job control interface operations */ -static struct job_interface_operations dhcp_job_operations = { - .done = ignore_job_done, - .kill = dhcp_job_kill, - .progress = ignore_job_progress, +static struct interface_operation dhcp_job_op[] = { + INTF_OP ( intf_close, struct dhcp_session *, dhcp_finished ), }; +/** DHCP job control interface descriptor */ +static struct interface_descriptor dhcp_job_desc = + INTF_DESC ( struct dhcp_session, job, dhcp_job_op ); + /**************************************************************************** * * Instantiators @@ -1424,7 +1410,7 @@ __weak void get_cached_dhcpack ( void ) {} * started; a positive return value indicates the success condition of * having fetched the appropriate data from cached information. */ -int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { +int start_dhcp ( struct interface *job, struct net_device *netdev ) { struct dhcp_session *dhcp; int rc; @@ -1440,7 +1426,7 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { if ( ! dhcp ) return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); - job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt ); + intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); @@ -1456,7 +1442,7 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) { dhcp_set_state ( dhcp, &dhcp_state_discover ); /* Attach parent interface, mortalise self, and return */ - job_plug_plug ( &dhcp->job, job ); + intf_plug_plug ( &dhcp->job, job ); ref_put ( &dhcp->refcnt ); return 0; @@ -1517,7 +1503,7 @@ static void pxebs_list ( struct dhcp_session *dhcp, void *raw, * If successful, the Boot Server ACK will be registered as an option * source. */ -int start_pxebs ( struct job_interface *job, struct net_device *netdev, +int start_pxebs ( struct interface *job, struct net_device *netdev, unsigned int pxe_type ) { struct setting pxe_discovery_control_setting = { .tag = DHCP_PXE_DISCOVERY_CONTROL }; @@ -1543,7 +1529,7 @@ int start_pxebs ( struct job_interface *job, struct net_device *netdev, if ( ! dhcp ) return -ENOMEM; ref_init ( &dhcp->refcnt, dhcp_free ); - job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt ); + intf_init ( &dhcp->job, &dhcp_job_desc, &dhcp->refcnt ); xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt ); timer_init ( &dhcp->timer, dhcp_timer_expired ); dhcp->netdev = netdev_get ( netdev ); @@ -1602,7 +1588,7 @@ int start_pxebs ( struct job_interface *job, struct net_device *netdev, dhcp_set_state ( dhcp, &dhcp_state_pxebs ); /* Attach parent interface, mortalise self, and return */ - job_plug_plug ( &dhcp->job, job ); + intf_plug_plug ( &dhcp->job, job ); ref_put ( &dhcp->refcnt ); return 0; |