5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2005 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 /****h* silcutil/SILC Async Operation Interface
24 * SILC Async Operation API is an interface that can be used to control
25 * asynchronous operations. All functions that take callback as argument
26 * should return SilcAsyncOperation context. That context then can be
27 * used to control, such as, abort the asynchronous operation. Using
28 * SILC Async Operation API, asynchronous functions can be controlled
31 * The SILC Async Operation API is divided in two levels; the underlaying
32 * operation level that implements the asynchronous operation, and the
33 * upper layer that can control the asynchronous operation. The operation
34 * layer must guarantee that if the upper layer aborts the asynchronous
35 * operation, no callback function will be called back to the upper layer.
36 * This must be remembered when implementing the operation layer.
43 /****s* silcutil/SilcAsyncOperationAPI/SilcAsyncOperation
47 * typedef struct SilcAsyncOperationObject *SilcAsyncOperation;
51 * The asynchronous operation context allocated by silc_async_alloc.
52 * The layer that implements the asynchronous operation allocates this
53 * context. The layer that receives this context can use it to control
54 * the underlaying asynchronous operation. It is also possible to use
55 * a pre-allocated context by using SilcAsyncOperationStruct instead
59 typedef struct SilcAsyncOperationObject *SilcAsyncOperation;
61 /****s* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationStruct
65 * typedef struct SilcAsyncOperationObject SilcAsyncOperationStruct;
69 * The asynchronous operation context that can be used as a pre-allocated
70 * context. This is initialized with silc_async_init. It need not
71 * be uninitialized. The layer that implements the asynchronous
72 * operation initializes this context. The layer that has access to this
73 * context can use it to control the underlaying asynchronous operation.
76 typedef struct SilcAsyncOperationObject SilcAsyncOperationStruct;
78 /****f* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationAbort
82 * typedef void (*SilcAsyncOperationAbort)(SilcAsyncOperation op,
87 * This callback is called when upper layer calls the silc_async_abort,
88 * and is used to actually perform the abortion of the asynchronous
89 * operation. The silc_async_free must not be called in this function.
91 * This callback type can also be provided to silc_async_abort function
92 * by the upper layer, if it wants that callback is called to the upper
93 * layer when aborting the operation.
96 typedef void (*SilcAsyncOperationAbort)(SilcAsyncOperation op,
99 /****f* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationPause
103 * typedef SilcBool (*SilcAsyncOperationPause)(SilcAsyncOperation op,
104 * SilcBool pause_operation,
109 * This callback is used to halt an operation, if upper layer calls the
110 * silc_async_halt function, or to resume an operation if upper layer
111 * calls the silc_async_resume, after it has earlier halted the operation.
112 * If this callback is implemented it is guaranteed that the asynchronous
113 * operation is not progressed when it is halted. If the `pause_operation'
114 * is TRUE the operation is halted. If it is FALSE, then the operation
115 * resumes its execution. This function returns TRUE if the operation
116 * was (or is going to be) halted or resumed, and FALSE on error.
119 typedef SilcBool (*SilcAsyncOperationPause)(SilcAsyncOperation op,
120 SilcBool pause_operation,
123 /* Upper layer functions for managing asynchronous operations. Layer
124 that has received SilcAsyncOperation context can control the async
125 operation with these functions. */
127 /****f* silcutil/SilcAsyncOperationAPI/silc_async_halt
131 * SilcBool silc_async_halt(SilcAsyncOperation op);
135 * Halt the execution of the asynchronous operation. If the operation
136 * supports this feature, it is guaranteed that the operation is halted
137 * and its execution is not progressed until the silc_async_resume function
138 * is called. The operation still can be aborted even if it is halted.
139 * If this function is not supported, calling this has no effect and the
140 * function returns FALSE. This function is for the upper layer that
141 * controls the asynchronous operation.
144 SilcBool silc_async_halt(SilcAsyncOperation op);
146 /****f* silcutil/SilcAsyncOperationAPI/silc_async_resume
150 * SilcBool silc_async_resume(SilcAsyncOperation op);
154 * Resume the execution of the asynchronous operation. If the halting of
155 * the operation was supported, then this function is used to resume the
156 * execution of the operation after it was halted. If this function is
157 * not supported, calling this has no effect and the function returns
158 * FALSE. This function is for the upper layer that controls the
159 * asynchronous operation.
162 SilcBool silc_async_resume(SilcAsyncOperation op);
164 /****f* silcutil/SilcAsyncOperationAPI/silc_async_abort
168 * void silc_async_abort(SilcAsyncOperation op,
169 * SilcAsyncOperationAbort abort_cb, void *context);
173 * This function is used by upper layer that received SilcAsyncOperation
174 * context from an asynchronous function, to abort the asynchronous
175 * operation. The `op' becomes invalid after this function returns.
176 * It is also guaranteed (assuming the use of this API is implemented
177 * correctly) that some other completion callback is not called after
178 * the operation was aborted. However, if the caller wants to receive
179 * a callback when aborting the caller may specify the `abort_cb' and
180 * `context' which will be called after the operation is aborted, but
181 * before the `op' becomes invalid. The `abort_cb' is called immediately
182 * inside this function.
185 void silc_async_abort(SilcAsyncOperation op,
186 SilcAsyncOperationAbort abort_cb, void *context);
188 /* The operation layer functions. The layer that performs the async
189 operation use these functions. */
191 /****f* silcutil/SilcAsyncOperationAPI/silc_async_alloc
195 * SilcAsyncOperation silc_async_alloc(SilcAsyncOperationAbort abort_cb,
196 * SilcAsyncOperationPause pause_cb,
201 * Start asynchronous operation, and assign `abort_cb' callback for it,
202 * which can be used by some upper layer to abort the asynchronous
203 * operation, by calling the silc_async_abort. The layer which calls
204 * this function must also call silc_async_free when the asynchronous
205 * operation is successfully completed. If it is aborted by upper layer
206 * then silc_async_free must not be called, since it is called by the
207 * silc_async_abort function.
209 * If the `pause_cb' is provided then the upper layer may also halt and
210 * then later resume the execution of the operation, by calling the
211 * silc_async_halt and silc_async_resume respectively. If `pause_cb' is
212 * not provided then these functions has no effect for this operation.
216 * SilcAsyncOperation silc_async_call(Callback callback, void *cb_context)
218 * SilcAsyncOperation op;
221 * // Allocate async operation so that caller can control us, like abort
222 * op = silc_async_alloc(silc_async_call_abort, NULL, ctx);
224 * // Start async operation in FSM
225 * silc_fsm_init(&ctx->fsm, ctx, fsm_destructor, ctx, schedule);
226 * silc_fsm_start(&ctx->fsm, first_state);
229 * // Return async operation for upper layer
234 SilcAsyncOperation silc_async_alloc(SilcAsyncOperationAbort abort_cb,
235 SilcAsyncOperationPause pause_cb,
238 /****f* silcutil/SilcAsyncOperationAPI/silc_async_init
242 * SilcBool silc_async_init(SilcAsyncOperation op,
243 * SilcAsyncOperationAbort abort_cb,
244 * SilcAsyncOperationPause pause_cb,
249 * Initializes and starts a pre-allocated asynchronous operation context,
250 * and assigns `abort_cb' callback for it, which can be used by some upper
251 * layer to abort the asynchronous operation, by calling the
252 * silc_async_abort. Since this use pre-allocated context, the function
253 * silc_async_free need not be called. This function is equivalent
254 * to silc_async_alloc except this does not allocate any memory. The `op'
255 * needs not be uninitialized.
257 * If the `pause_cb' is provided then the upper layer may also halt and
258 * then later resume the execution of the operation, by calling the
259 * silc_async_halt and silc_async_resume respectively. If `pause_cb' is
260 * not provided then these functions has no effect for this operation.
263 SilcBool silc_async_init(SilcAsyncOperation op,
264 SilcAsyncOperationAbort abort_cb,
265 SilcAsyncOperationPause pause_cb,
268 /****f* silcutil/SilcAsyncOperationAPI/silc_async_free
272 * void silc_async_free(SilcAsyncOperation op);
276 * Stop the asynchronous operation. If the asynchronous operation ended
277 * normally (ie. it was not aborted) this function must be called by the
278 * caller who called silc_async_alloc. The `op' will become invalid after
279 * this and the upper layer must not call silc_async_abort after this
280 * function is called. The layer that calls this, must call some other
281 * completion callback to the upper layer, so that it knows that the
282 * asynchronous operation is completed.
285 void silc_async_free(SilcAsyncOperation op);
287 /****f* silcutil/SilcAsyncOperationAPI/silc_async_get_context
291 * void *silc_async_get_context(SilcAsyncOperation op);
295 * Returns the context that was given to the silc_async_alloc or
299 void *silc_async_get_context(SilcAsyncOperation op);
301 #include "silcasync_i.h"
303 #endif /* SILCASYNC_H */