/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
1
#ifndef __H_MAIN_LOOP__
2
#define __H_MAIN_LOOP__
3
4
/*
5
Copyright (c) 2013-2016 Gustav Hartvigsson
6
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
copies of the Software, and to permit persons to whom the Software is
12
furnished to do so, subject to the following conditions:
13
14
The above copyright notice and this permission notice shall be included in
15
all copies or substantial portions of the Software.
16
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
THE SOFTWARE.
24
 */
25
26
#include "defs.h"
27
#include "Func.h"
28
#include "utils.h"
29
#include "utils.h"
30
31
S_BEGIN_DECLS
32
33
/**
34
 * @file
35
 * @defgroup SMainLoop SMainLoop
36
 * @addtogroup SMainLoop
37
 * @{
38
 * The main loop system consits of two rings. The first ring is for high
39
 * priority stuffs that need to be run often. The second ring is run much less
40
 * often than the first ring.
41
 *
42
 * The sectond ring is put in the next state only after the first ring has done
43
 * what is required of it.
44
 *
45
 * Please note that if you are doing pull/push of data via streams, only use one
46
 * or the other, do not mix ring 1 and ring 2 as that may lead to filling
47
 * or depleating of buffers.
48
 *
49
 * Here is an overwiev of the main loop:
50
 * @code
51
 *  Ring 1
52
 *   [Do event handlers] -> [IO Push] -> [IO Pull] -> [Do Workers] ->
53
 *       ^                                                  |
54
 *       |                                                  |
55
 *       -------------- [Sleep] <---  [Ring 2 Next] <--------
56
 *
57
 *  Ring 2
58
 *   [Do event handlers] -> [IO Push] -> [IO PULL]
59
 *         ^                                |
60
 *         |                                |
61
 *         ---------  [Do Workers] <---------
62
 * @endcode
63
 */
64
65
/* -----------------------------------------------------------------------------
66
 * declarations
67
 * -----------------------------------------------------------------------------
68
 */
69
70
/**
71
 * The structure that represents the main loop. It is seldom required to
72
 * directly interact with objcets of this type.
73
 */
74
typedef struct SMainLoop SMainLoop;
75
76
/**
77
 * The stats that the main loop can be in.
78
 */
79
typedef enum {
80
  S_MAIN_LOOP_STATE_NONE,
81
  S_MAIN_LOOP_STATE_EVENT,
82
  S_MAIN_LOOP_STATE_IO_PUSH,
83
  S_MAIN_LOOP_STATE_IO_PULL,
84
  S_MAIN_LOOP_STATE_DO_WORKERS,
85
  S_MAIN_LOOP_STATE_RING_TWO_NEXT,
86
  S_MAIN_LOOP_STATE_SLEEP,
87
  S_MAIN_LOOP_STATE_LAST
88
} SMainLoopState;
89
90
/**
91
 * The namse of the states.
92
 */
93
S_UNUSED static schar *
94
SMainLoopStateName [] = {
95
  "NONE",
96
  "Event",
97
  "Push",
98
  "Pull",
99
  "Do Work",
100
  "Ring Two Next",
101
  "Sleep",
102
  "NONE",
103
  0x0,
104
  0x0
105
};
106
107
/**
108
 * Get the name of the state. For use in bindings.
109
 */
110
schar *
111
s_main_loop_state_get_name (SMainLoopState state);
112
113
/**
114
 * The different rings.
115
 */
116
typedef enum {
117
  S_MAIN_LOOP_RING_NONE,
118
  S_MAIN_LOOP_RING_ONE,
119
  S_MAIN_LOOP_RING_TWO,
120
  S_MAIN_LOOP_RING_LAST
121
} SMainLoopRing;
122
123
/**
124
 * The names of the rings
125
 */
126
S_UNUSED static schar *
127
SMainLoopRingName [] = {
128
  "NONE",
129
  "Ring One",
130
  "Ring Two",
131
  "NONE",
132
  0x0,
133
  0x0
134
};
135
136
/**
137
 * Get name of the ring. For used in bindings.
138
 */
139
schar *
140
s_main_loop_ring_get_name (SMainLoopRing ring);
141
142
/* -----------------------------------------------------------------------------
143
 * definition of the real functions and stuffs.
144
 * -----------------------------------------------------------------------------
145
 */
146
147
/** @brief
148
 * Create a new MainLoop.
149
 *
150
 * This is something that usually is not needed, and unless you know exectly
151
 * what you are doing, it is never recomeded to create your own mainloops,
152
 * instead use @ref s_main_loop_get_default.
153
 */
154
SMainLoop *
155
s_main_loop_new ();
156
157
/** @brief
158
 * Get the default mainloop.
159
 *
160
 * The default mainloop is the mainloop that it is recomeded to interact with.
161
 */
162
SMainLoop *
163
s_main_loop_get_default ();
164
165
/** @brief
166
 * Run a mainloop.
167
 *
168
 * This is usually the way that applications are started, after all pre-start
169
 * stuffs are done.
170
 *
171
 * @param loop The mainloop to be run.
172
 */
173
void
174
s_main_loop_run (SMainLoop * loop);
175
176
177
/** @brief
178
 * Quit the mainloop. This is usually the way that applications are quit.
179
 *
180
 * When this function is run, it is important that all data has been freed.
181
 * To assure that this has happened you can add teardown handlers to the
182
 * main loop using the @ref s_main_loop_add_teardown_handler function,
183
 * these handlers will be run when s_main_loop_quit is run.
184
 */
185
void
186
s_main_loop_quit (SMainLoop * loop);
187
188
/** @brief
189
 * Add a reference to the main loop.
190
 *
191
 * This may or may not be useful. When the reference count reaches zero the
192
 * main loop will be free using @ref s_main_loop_quit.
193
 */
194
void
195
s_main_loop_ref (SMainLoop * loop);
196
197
/** @brief
198
 * Remove a reference to the main loop.
199
 *
200
 * This may or may not be useful. When the reference count reaches zero the
201
 * main loop will be free using @ref s_main_loop_quit.
202
 */
203
void
204
s_main_loop_unref (SMainLoop * loop);
205
206
/** @brief.
207
 * Add an event handler to the main loop
208
 *
209
 * @param loop The main loop to add the event hadler to.
210
 * @param ring To what ring to add the event handler to. (Ring 1 for high
211
 *             priority handlers, and ring 2 for low priority handlers.)
212
 * @param event_handler The event handler to be added to the main loop.
213
 * @param user_data The user data to be passed to the event handler. This
214
 *                  could be data that is relevent to the componant where the
215
 *                  event handler originates from.
216
 */
217
void
218
s_main_loop_add_event_handler (SMainLoop * loop,
219
			       SMainLoopRing ring,
220
			       RunFunc event_handler,
221
			       spointer user_data);
222
223
/** @brief
224
 * Add an I/O push event to the main loop
225
 *
226
 * @param loop the main loop to add the I/O push event to.
227
 * @param ring The ring to add the I/O push event to.
228
 * @param push_callback The callback that prepforms the I/O push.
229
 * @param user_data A pointer to the data to be provided to the callback.
230
 */
231
void
232
s_main_loop_add_io_push (SMainLoop * loop,
233
			 SMainLoopRing ring,
234
			 RunFunc push_callback,
235
			 spointer user_data);
236
237
/** @brief
238
 * Add a I/O pull event to the main loop.
239
 *
240
 * @param loop The loop to add the I/O pull event to.
241
 * @param ring The ring to add the evet to.
242
 * @param pull_callback The callback to be performs the I/O pull.
243
 * @param user_data The data to be provided to the callback.
244
 */
245
void
246
s_main_loop_add_io_pull (SMainLoop * loop,
247
			 SMainLoopRing ring,
248
			 RunFunc pull_callback,
249
			 spointer user_data);
250
251
/** @brief
252
 * Add a worker to the main loop.
253
 *
254
 * @param loop The loop to add the worker to.
255
 * @param ring The ring to add the worker to.
256
 * @param pull_callback The worker callback.
257
 * @param user_data The data to be provided to the callback.
258
 */
259
void
260
s_main_loop_add_worker (SMainLoop * loop,
261
			SMainLoopRing ring,
262
			RunFunc worker_callback,
263
			spointer user_data);
264
265
/** @brief
266
 * Add a teardown handler.
267
 *
268
 * A teardown handler is a function that
269
 *
270
 * @param loop The loop to add the teardown handler to.
271
 * @param teardown_handler The teardown handler.
272
 * @param self The self object that is to be torn down.
273
 * @param user_data A pointer to be provided to the callback.
274
 */
275
void
276
s_main_loop_add_teardown_handler (SMainLoop * loop,
277
				  Callback teardown_handler,
278
				  spointer self,
279
				  spointer user_data);
280
281
282
/**
283
 * @section THREAD_SAFTEY THREAD SAFTEY
284
 */
285
inline void FOOL_DOXYGEN ();
286
287
/** @brief
288
 * lock the main loop form tampering from other threads.
289
 *
290
 * This function locks the main loop's mutex so that no changes can
291
 * be done to the loop whilst it is locked.
292
 *
293
 * @param loop The main loop to be locked.
294
 */
295
void
296
s_main_loop_lock (SMainLoop * loop);
297
298
299
/** @brief
300
 * lock the main loop form tampering from other threads.
301
 *
302
 * This function locks the main loop's mutex so that no changes can
303
 * be done to the loop whilst it is locked.
304
 *
305
 * @param loop The loop to be unlocked.
306
 */
307
void
308
s_main_loop_unlock (SMainLoop * loop);
309
310
311
/**
312
 * @}
313
 */
314
315
S_END_DECLS
316
317
318
#endif /* __H_MAIN_LOOP__ */