|
@@ -93,6 +93,42 @@ aid_t async_init ( struct async *async, struct async_operations *aop,
|
93
|
93
|
return async->aid;
|
94
|
94
|
}
|
95
|
95
|
|
|
96
|
+/**
|
|
97
|
+ * Uninitialise an asynchronous operation
|
|
98
|
+ *
|
|
99
|
+ * @v async Asynchronous operation
|
|
100
|
+ *
|
|
101
|
+ * Abandon an asynchronous operation without signalling the parent.
|
|
102
|
+ * You may do this only during the period between calling async_init()
|
|
103
|
+ * and returning to the parent for the first time. It is designed to
|
|
104
|
+ * simplify the error paths of asynchronous operations that themselves
|
|
105
|
+ * spawn further asynchronous operations.
|
|
106
|
+ *
|
|
107
|
+ * An example may help:
|
|
108
|
+ *
|
|
109
|
+ * int start_something ( ..., struct async *parent ) {
|
|
110
|
+ * struct my_data_structure *myself;
|
|
111
|
+ *
|
|
112
|
+ * ... allocate memory for myself ...
|
|
113
|
+ *
|
|
114
|
+ * async_init ( &myself->async, &my_async_operations, parent );
|
|
115
|
+ * if ( ( rc = start_child_operation ( ..., &myself->async ) ) != 0 ) {
|
|
116
|
+ * async_uninit ( &myself->async );
|
|
117
|
+ * return rc;
|
|
118
|
+ * }
|
|
119
|
+ *
|
|
120
|
+ * return 0;
|
|
121
|
+ * }
|
|
122
|
+ *
|
|
123
|
+ * It is valid to call async_uninit() on an asynchronous operation
|
|
124
|
+ * that has not yet been initialised (i.e. a zeroed-out @c struct @c
|
|
125
|
+ * async).
|
|
126
|
+ */
|
|
127
|
+void async_uninit ( struct async *async ) {
|
|
128
|
+ if ( async->parent )
|
|
129
|
+ list_del ( &async->siblings );
|
|
130
|
+}
|
|
131
|
+
|
96
|
132
|
/**
|
97
|
133
|
* SIGCHLD 'ignore' handler
|
98
|
134
|
*
|