Added async_uninit() to simplify failure paths.
authorMichael Brown <mcb30@etherboot.org>
Thu, 18 Jan 2007 03:29:40 +0000 (03:29 +0000)
committerMichael Brown <mcb30@etherboot.org>
Thu, 18 Jan 2007 03:29:40 +0000 (03:29 +0000)
src/core/async.c
src/include/gpxe/async.h

index 95bbc05..26b27f0 100644 (file)
@@ -93,6 +93,42 @@ aid_t async_init ( struct async *async, struct async_operations *aop,
        return async->aid;
 }
 
+/**
+ * Uninitialise an asynchronous operation
+ *
+ * @v async            Asynchronous operation
+ *
+ * Abandon an asynchronous operation without signalling the parent.
+ * You may do this only during the period between calling async_init()
+ * and returning to the parent for the first time.  It is designed to
+ * simplify the error paths of asynchronous operations that themselves
+ * spawn further asynchronous operations.
+ *
+ * An example may help:
+ *
+ *     int start_something ( ..., struct async *parent ) {
+ *         struct my_data_structure *myself;
+ *
+ *         ... allocate memory for myself ...
+ *
+ *         async_init ( &myself->async, &my_async_operations, parent );
+ *         if ( ( rc = start_child_operation ( ..., &myself->async ) ) != 0 ) {
+ *             async_uninit ( &myself->async );
+ *             return rc;
+ *         }
+ *
+ *         return 0;
+ *     }
+ *
+ * It is valid to call async_uninit() on an asynchronous operation
+ * that has not yet been initialised (i.e. a zeroed-out @c struct @c
+ * async).
+ */
+void async_uninit ( struct async *async ) {
+       if ( async->parent )
+               list_del ( &async->siblings );
+}
+
 /**
  * SIGCHLD 'ignore' handler
  *
index b1ca1a1..42ee93d 100644 (file)
@@ -138,6 +138,7 @@ extern struct async_operations orphan_async_operations;
 
 extern aid_t async_init ( struct async *async, struct async_operations *aop,
                          struct async *parent );
+extern void async_uninit ( struct async *async );
 extern void async_ignore_signal ( struct async *async, enum signal signal );
 extern void async_signal ( struct async *async, enum signal signal );
 extern void async_signal_children ( struct async *async, enum signal signal );