From 6601a7da6a8cce70348eea1acbcf4296657188b8 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 18 Jan 2007 03:29:40 +0000 Subject: [PATCH] Added async_uninit() to simplify failure paths. --- src/core/async.c | 36 ++++++++++++++++++++++++++++++++++++ src/include/gpxe/async.h | 1 + 2 files changed, 37 insertions(+) diff --git a/src/core/async.c b/src/core/async.c index 95bbc057..26b27f0b 100644 --- a/src/core/async.c +++ b/src/core/async.c @@ -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 * diff --git a/src/include/gpxe/async.h b/src/include/gpxe/async.h index b1ca1a1c..42ee93d5 100644 --- a/src/include/gpxe/async.h +++ b/src/include/gpxe/async.h @@ -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 );