Added SILC Server library.
[silc.git] / lib / silcutil / silcasync.h
1 /*
2
3   silcasync.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 /****h* silcutil/SILC Async Operation Interface
21  *
22  * DESCRIPTION
23  *
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
29  * and aborted safely.
30  *
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.
37  *
38  ***/
39
40 #ifndef SILCASYNC_H
41 #define SILCASYNC_H
42
43 /****s* silcutil/SilcAsyncOperationAPI/SilcAsyncOperation
44  *
45  * NAME
46  *
47  *    typedef struct SilcAsyncOperationObject *SilcAsyncOperation;
48  *
49  * DESCRIPTION
50  *
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
56  *    SilcAsyncOperation.
57  *
58  ***/
59 typedef struct SilcAsyncOperationObject *SilcAsyncOperation;
60
61 /****s* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationStruct
62  *
63  * NAME
64  *
65  *    typedef struct SilcAsyncOperationObject SilcAsyncOperationStruct;
66  *
67  * DESCRIPTION
68  *
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.
74  *
75  ***/
76 typedef struct SilcAsyncOperationObject SilcAsyncOperationStruct;
77
78 /****f* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationAbort
79  *
80  * SYNOPSIS
81  *
82  *    typedef void (*SilcAsyncOperationAbort)(SilcAsyncOperation op,
83  *                                            void *context);
84  *
85  * DESCRIPTION
86  *
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.
90  *
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.
94  *
95  ***/
96 typedef void (*SilcAsyncOperationAbort)(SilcAsyncOperation op,
97                                         void *context);
98
99 /****f* silcutil/SilcAsyncOperationAPI/SilcAsyncOperationPause
100  *
101  * SYNOPSIS
102  *
103  *    typedef SilcBool (*SilcAsyncOperationPause)(SilcAsyncOperation op,
104  *                                            SilcBool pause_operation,
105  *                                            void *context);
106  *
107  * DESCRIPTION
108  *
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.
117  *
118  ***/
119 typedef SilcBool (*SilcAsyncOperationPause)(SilcAsyncOperation op,
120                                             SilcBool pause_operation,
121                                             void *context);
122
123 /* Upper layer functions for managing asynchronous operations.  Layer
124    that has received SilcAsyncOperation context can control the async
125    operation with these functions. */
126
127 /****f* silcutil/SilcAsyncOperationAPI/silc_async_halt
128  *
129  * SYNOPSIS
130  *
131  *    SilcBool silc_async_halt(SilcAsyncOperation op);
132  *
133  * DESCRIPTION
134  *
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.
142  *
143  ***/
144 SilcBool silc_async_halt(SilcAsyncOperation op);
145
146 /****f* silcutil/SilcAsyncOperationAPI/silc_async_resume
147  *
148  * SYNOPSIS
149  *
150  *    SilcBool silc_async_resume(SilcAsyncOperation op);
151  *
152  * DESCRIPTION
153  *
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.
160  *
161  ***/
162 SilcBool silc_async_resume(SilcAsyncOperation op);
163
164 /****f* silcutil/SilcAsyncOperationAPI/silc_async_abort
165  *
166  * SYNOPSIS
167  *
168  *    void silc_async_abort(SilcAsyncOperation op,
169  *                          SilcAsyncOperationAbort abort_cb, void *context);
170  *
171  * DESCRIPTION
172  *
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.
183  *
184  ***/
185 void silc_async_abort(SilcAsyncOperation op,
186                       SilcAsyncOperationAbort abort_cb, void *context);
187
188 /* The operation layer functions.  The layer that performs the async
189    operation use these functions. */
190
191 /****f* silcutil/SilcAsyncOperationAPI/silc_async_alloc
192  *
193  * SYNOPSIS
194  *
195  *    SilcAsyncOperation silc_async_alloc(SilcAsyncOperationAbort abort_cb,
196  *                                        SilcAsyncOperationPause pause_cb,
197  *                                        void *context);
198  *
199  * DESCRIPTION
200  *
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.
208  *
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.
213  *
214  * EXAMPLE
215  *
216  *    SilcAsyncOperation silc_async_call(Callback callback, void *cb_context)
217  *    {
218  *      SilcAsyncOperation op;
219  *      ...
220  *
221  *      // Allocate async operation so that caller can control us, like abort
222  *      op = silc_async_alloc(silc_async_call_abort, NULL, ctx);
223  *
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);
227  *      ...
228  *
229  *      // Return async operation for upper layer
230  *      return op;
231  *    }
232  *
233  ***/
234 SilcAsyncOperation silc_async_alloc(SilcAsyncOperationAbort abort_cb,
235                                     SilcAsyncOperationPause pause_cb,
236                                     void *context);
237
238 /****f* silcutil/SilcAsyncOperationAPI/silc_async_init
239  *
240  * SYNOPSIS
241  *
242  *    SilcBool silc_async_init(SilcAsyncOperation op,
243  *                         SilcAsyncOperationAbort abort_cb,
244  *                         SilcAsyncOperationPause pause_cb,
245  *                         void *context);
246  *
247  * DESCRIPTION
248  *
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.
255  *
256  *    If the `pause_cb' is provided then the upper layer may also halt and
257  *    then later resume the execution of the operation, by calling the
258  *    silc_async_halt and silc_async_resume respectively.  If `pause_cb' is
259  *    not provided then these functions has no effect for this operation.
260  *
261  ***/
262 SilcBool silc_async_init(SilcAsyncOperation op,
263                          SilcAsyncOperationAbort abort_cb,
264                          SilcAsyncOperationPause pause_cb,
265                          void *context);
266
267 /****f* silcutil/SilcAsyncOperationAPI/silc_async_free
268  *
269  * SYNOPSIS
270  *
271  *    void silc_async_free(SilcAsyncOperation op);
272  *
273  * DESCRIPTION
274  *
275  *    Stop the asynchronous operation.  If the asynchronous operation ended
276  *    normally (ie. it was not aborted) this function must be called by the
277  *    caller who called silc_async_alloc.  The `op' will become invalid after
278  *    this and the upper layer must not call silc_async_abort after this
279  *    function is called.  The layer that calls this, must call some other
280  *    completion callback to the upper layer, so that it knows that the
281  *    asynchronous operation is completed.
282  *
283  ***/
284 void silc_async_free(SilcAsyncOperation op);
285
286 /****f* silcutil/SilcAsyncOperationAPI/silc_async_get_context
287  *
288  * SYNOPSIS
289  *
290  *    void *silc_async_get_context(SilcAsyncOperation op);
291  *
292  * DESCRIPTION
293  *
294  *    Returns the context that was given to the silc_async_alloc or
295  *    silc_async_init.
296  *
297  ***/
298 void *silc_async_get_context(SilcAsyncOperation op);
299
300 #include "silcasync_i.h"
301
302 #endif /* SILCASYNC_H */