/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#pragma once

/*
Copyright (c) 2013-2016 Gustav Hartvigsson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */

#include "defs.h"
#include "Func.h"
#include "utils.h"
#include "utils.h"

S_BEGIN_DECLS

/**
 * @file
 * @defgroup SMainLoop SMainLoop
 * @addtogroup SMainLoop
 * @{
 * The main loop system consits of two rings. The first ring is for high
 * priority stuffs that need to be run often. The second ring is run much less
 * often than the first ring.
 *
 * The sectond ring is put in the next state only after the first ring has done
 * what is required of it.
 *
 * Please note that if you are doing pull/push of data via streams, only use one
 * or the other, do not mix ring 1 and ring 2 as that may lead to filling
 * or depleating of buffers.
 *
 * Here is an overwiev of the main loop:
 * @code
 *  Ring 1
 *   [Do event handlers] -> [IO Push] -> [IO Pull] -> [Do Workers] ->
 *       ^                                                  |
 *       |                                                  |
 *       -------------- [Sleep] <---  [Ring 2 Next] <--------
 *
 *  Ring 2
 *   [Do event handlers] -> [IO Push] -> [IO PULL]
 *         ^                                |
 *         |                                |
 *         ---------  [Do Workers] <---------
 * @endcode
 */

/* -----------------------------------------------------------------------------
 * declarations
 * -----------------------------------------------------------------------------
 */

/**
 * The structure that represents the main loop. It is seldom required to
 * directly interact with objcets of this type.
 */
typedef struct SMainLoop SMainLoop;

/**
 * The stats that the main loop can be in.
 */
typedef enum {
  S_MAIN_LOOP_STATE_NONE,
  S_MAIN_LOOP_STATE_EVENT,
  S_MAIN_LOOP_STATE_IO_PUSH,
  S_MAIN_LOOP_STATE_IO_PULL,
  S_MAIN_LOOP_STATE_DO_WORKERS,
  S_MAIN_LOOP_STATE_RING_TWO_NEXT,
  S_MAIN_LOOP_STATE_SLEEP,
  S_MAIN_LOOP_STATE_LAST
} SMainLoopState;

/**
 * The namse of the states.
 */
S_UNUSED static schar *
SMainLoopStateName [] = {
  "NONE",
  "Event",
  "Push",
  "Pull",
  "Do Work",
  "Ring Two Next",
  "Sleep",
  "NONE",
  0x0,
  0x0
};

/**
 * Get the name of the state. For use in bindings.
 */
S_EXPORTED
schar *
s_main_loop_state_get_name (SMainLoopState state);

/**
 * The different rings.
 */
typedef enum {
  S_MAIN_LOOP_RING_NONE,
  S_MAIN_LOOP_RING_ONE,
  S_MAIN_LOOP_RING_TWO,
  S_MAIN_LOOP_RING_LAST
} SMainLoopRing;

/**
 * The names of the rings
 */
S_UNUSED static schar *
SMainLoopRingName [] = {
  "NONE",
  "Ring One",
  "Ring Two",
  "NONE",
  0x0,
  0x0
};

/**
 * Get name of the ring. For used in bindings.
 */
S_EXPORTED
schar *
s_main_loop_ring_get_name (SMainLoopRing ring);

/* -----------------------------------------------------------------------------
 * definition of the real functions and stuffs.
 * -----------------------------------------------------------------------------
 */

/** @brief
 * Create a new MainLoop.
 *
 * This is something that usually is not needed, and unless you know exectly
 * what you are doing, it is never recomeded to create your own mainloops,
 * instead use @ref s_main_loop_get_default.
 */
S_EXPORTED
SMainLoop *
s_main_loop_new ();

/** @brief
 * Get the default mainloop.
 *
 * The default mainloop is the mainloop that it is recomeded to interact with.
 */
S_EXPORTED
SMainLoop *
s_main_loop_get_default ();

/** @brief
 * Run a mainloop.
 *
 * This is usually the way that applications are started, after all pre-start
 * stuffs are done.
 *
 * @param loop The mainloop to be run.
 */
S_EXPORTED
void
s_main_loop_run (SMainLoop * loop);


/** @brief
 * Quit the mainloop. This is usually the way that applications are quit.
 *
 * When this function is run, it is important that all data has been freed.
 * To assure that this has happened you can add teardown handlers to the
 * main loop using the @ref s_main_loop_add_teardown_handler function,
 * these handlers will be run when s_main_loop_quit is run.
 */
S_EXPORTED
void
s_main_loop_quit (SMainLoop * loop);

/** @brief
 * Add a reference to the main loop.
 *
 * This may or may not be useful. When the reference count reaches zero the
 * main loop will be free using @ref s_main_loop_quit.
 */
S_EXPORTED
void
s_main_loop_ref (SMainLoop * loop);

/** @brief
 * Remove a reference to the main loop.
 *
 * This may or may not be useful. When the reference count reaches zero the
 * main loop will be free using @ref s_main_loop_quit.
 */
S_EXPORTED
void
s_main_loop_unref (SMainLoop * loop);

/** @brief.
 * Add an event handler to the main loop
 *
 * @param loop The main loop to add the event hadler to.
 * @param ring To what ring to add the event handler to. (Ring 1 for high
 *             priority handlers, and ring 2 for low priority handlers.)
 * @param event_handler The event handler to be added to the main loop.
 * @param user_data The user data to be passed to the event handler. This
 *                  could be data that is relevent to the componant where the
 *                  event handler originates from.
 */
S_EXPORTED
void
s_main_loop_add_event_handler (SMainLoop * loop,
                               SMainLoopRing ring,
                               RunFunc event_handler,
                               spointer user_data);

/** @brief
 * Add an I/O push event to the main loop
 *
 * @param loop the main loop to add the I/O push event to.
 * @param ring The ring to add the I/O push event to.
 * @param push_callback The callback that prepforms the I/O push.
 * @param user_data A pointer to the data to be provided to the callback.
 */
S_EXPORTED
void
s_main_loop_add_io_push (SMainLoop * loop,
                         SMainLoopRing ring,
                         RunFunc push_callback,
                         spointer user_data);

/** @brief
 * Add a I/O pull event to the main loop.
 *
 * @param loop The loop to add the I/O pull event to.
 * @param ring The ring to add the evet to.
 * @param pull_callback The callback to be performs the I/O pull.
 * @param user_data The data to be provided to the callback.
 */
S_EXPORTED
void
s_main_loop_add_io_pull (SMainLoop * loop,
			 SMainLoopRing ring,
			 RunFunc pull_callback,
			 spointer user_data);

/** @brief
 * Add a worker to the main loop.
 *
 * @param loop The loop to add the worker to.
 * @param ring The ring to add the worker to.
 * @param pull_callback The worker callback.
 * @param user_data The data to be provided to the callback.
 */
S_EXPORTED
void
s_main_loop_add_worker (SMainLoop * loop,
                        SMainLoopRing ring,
                        RunFunc worker_callback,
                        spointer user_data);

/** @brief
 * Add a teardown handler.
 *
 * A teardown handler is a function that
 *
 * @param loop The loop to add the teardown handler to.
 * @param teardown_handler The teardown handler.
 * @param self The self object that is to be torn down.
 * @param user_data A pointer to be provided to the callback.
 */
S_EXPORTED
void
s_main_loop_add_teardown_handler (SMainLoop * loop,
                                  Callback teardown_handler,
                                  spointer self,
                                  spointer user_data);


/** @brief
 * @section THREAD_SAFTEY THREAD SAFTEY
 */
inline void FOOL_DOXYGEN ();


/** @brief
 * lock the main loop form tampering from other threads.
 *
 * This function locks the main loop's mutex so that no changes can
 * be done to the loop whilst it is locked.
 *
 * @param loop The main loop to be locked.
 */
S_EXPORTED
void
s_main_loop_lock (SMainLoop * loop);


/** @brief
 * lock the main loop form tampering from other threads.
 *
 * This function locks the main loop's mutex so that no changes can
 * be done to the loop whilst it is locked.
 *
 * @param loop The loop to be unlocked.
 */
S_EXPORTED
void
s_main_loop_unlock (SMainLoop * loop);

/* This has to be put last to remove undefined warning */
inline void FOOL_DOXYGEN () {};

/**
 * @}
 */

S_END_DECLS