summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorMichael Brown2017-02-02 16:49:21 +0100
committerMichael Brown2017-02-02 16:49:21 +0100
commit23b788e5cdd7fcfa863a476a1448870ac3cf0103 (patch)
tree71adb0fc07eef44c176e7e8b43d903e9d6bba47e /src/core
parent[time] Report attempts to use timers before initialisation (diff)
downloadipxe-23b788e5cdd7fcfa863a476a1448870ac3cf0103.tar.gz
ipxe-23b788e5cdd7fcfa863a476a1448870ac3cf0103.tar.xz
ipxe-23b788e5cdd7fcfa863a476a1448870ac3cf0103.zip
[interface] Provide the ability to shut down multiple interfaces
Shutting down (and optionally restarting) multiple interfaces is fraught with problems if there are loops in the interface connectivity (e.g. the HTTP content-decoded and transfer-decoded interfaces, which will generally loop back to each other). Various workarounds currently exist across the codebase, generally involving preceding calls to intf_nullify() to avoid problems due to known loops. Provide intfs_shutdown() and intfs_restart() to allow all of an object's interfaces to be shut down (or restarted) in a single call, without having to worry about potential external loops. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/interface.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/core/interface.c b/src/core/interface.c
index f7802be0..402aa454 100644
--- a/src/core/interface.c
+++ b/src/core/interface.c
@@ -291,6 +291,41 @@ void intf_shutdown ( struct interface *intf, int rc ) {
}
/**
+ * Shut down multiple object interfaces
+ *
+ * @v intfs Object interfaces
+ * @v rc Reason for close
+ */
+void intfs_vshutdown ( va_list intfs, int rc ) {
+ struct interface *intf;
+ va_list tmp;
+
+ /* Nullify all interfaces to avoid potential loops */
+ va_copy ( tmp, intfs );
+ while ( ( intf = va_arg ( tmp, struct interface * ) ) )
+ intf_nullify ( intf );
+ va_end ( tmp );
+
+ /* Shut down all interfaces */
+ while ( ( intf = va_arg ( intfs, struct interface * ) ) )
+ intf_shutdown ( intf, rc );
+}
+
+/**
+ * Shut down multiple object interfaces
+ *
+ * @v rc Reason for close
+ * @v ... Object interfaces
+ */
+void intfs_shutdown ( int rc, ... ) {
+ va_list intfs;
+
+ va_start ( intfs, rc );
+ intfs_vshutdown ( intfs, rc );
+ va_end ( intfs );
+}
+
+/**
* Shut down and restart an object interface
*
* @v intf Object interface
@@ -317,6 +352,40 @@ void intf_restart ( struct interface *intf, int rc ) {
}
/**
+ * Shut down and restart multiple object interfaces
+ *
+ * @v intfs Object interfaces
+ * @v rc Reason for close
+ */
+void intfs_vrestart ( va_list intfs, int rc ) {
+ struct interface *intf;
+ va_list tmp;
+
+ /* Shut down all interfaces */
+ va_copy ( tmp, intfs );
+ intfs_vshutdown ( tmp, rc );
+ va_end ( tmp );
+
+ /* Reinitialise all interfaces */
+ while ( ( intf = va_arg ( intfs, struct interface * ) ) )
+ intf_reinit ( intf );
+}
+
+/**
+ * Shut down and restart multiple object interfaces
+ *
+ * @v rc Reason for close
+ * @v ... Object interfaces
+ */
+void intfs_restart ( int rc, ... ) {
+ va_list intfs;
+
+ va_start ( intfs, rc );
+ intfs_vrestart ( intfs, rc );
+ va_end ( intfs );
+}
+
+/**
* Poke an object interface
*
* @v intf Object interface