/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
#include "MainLoop.h"
2
#include "Thread.h"
3
#include "LinkedList.h"
4
5
/*
6
Copyright (c) 2013-2016 Gustav Hartvigsson
7
8
Permission is hereby granted, free of charge, to any person obtaining a copy
9
of this software and associated documentation files (the "Software"), to deal
10
in the Software without restriction, including without limitation the rights
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
copies of the Software, and to permit persons to whom the Software is
13
furnished to do so, subject to the following conditions:
14
15
The above copyright notice and this permission notice shall be included in
16
all copies or substantial portions of the Software.
17
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
THE SOFTWARE.
25
 */
26
27
/*
28
 * The default mainloop, it is hidden.
29
 */
30
SMainLoop *
31
_default_main_loop = NULL;
32
33
/*
34
 * The items that are held by the linked lists in SMainLoop.
35
 */
36
typedef struct SMainLoopItem {
37
  SMainLoopState state; /* in what list should this item be? */
38
  sboolean is_alive; /* If this is TRUE then this can be removed. */
39
40
  RunFunc callback; /* The callback that is run. */
41
  spointer user_data; /* Pointer to the user data that was provided. */
42
} SMainLoopItem;
43
44
typedef struct  SMainLoopTeardownHandler {
45
  Callback teardown_handler;
46
47
  spointer obj_self;
48
  spointer user_data;
49
50
} SMainLoopTeardownHandler;
51
52
/* This is the freeing function for MainLoopTeardownHandler objcets it also
53
 * calls the teardown handler.
54
 *
55
 * This reduces the iteration time for the teardown.
56
 */
57
void
58
_s_main_loop_teardown_handerer_obj_free (SMainLoopTeardownHandler * self);
59
60
struct SMainLoop {
61
  suint ref_count;
62
  SMainLoopState ring_1_state;
63
  SMainLoopState ring_2_state;
64
  sboolean is_run;
65
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
66
  SMutex * mutex[S_MAIN_LOOP_RING_LAST][S_MAIN_LOOP_STATE_LAST];
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
67
68
  SLinkedList * ring_1_event_handler_list;
69
  SLinkedList * ring_1_io_push_list;
70
  SLinkedList * ring_1_io_pull_list;
71
  SLinkedList * ring_1_workers_list;
72
73
  SLinkedList * ring_2_event_handler_list;
74
  SLinkedList * ring_2_io_push_list;
75
  SLinkedList * ring_2_io_pull_list;
76
  SLinkedList * ring_2_workers_list;
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
77
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
78
  SLinkedList * teardown_handler_list;
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
79
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
80
  SMutex * teardown_handler_mutex;
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
81
};
82
83
schar *
84
s_main_loop_state_get_name (SMainLoopState state) {
85
  return SMainLoopStateName[state];
86
}
87
88
schar *
89
s_main_loop_ring_get_name (SMainLoopRing ring) {
90
  return SMainLoopStateName[ring];
91
}
92
93
/* ************************************************************************** */
94
95
void
96
_s_main_loop_do_list (SLinkedList * event_handler_list);
97
98
void
99
_s_main_loop_do_ring_two (SMainLoop * self);
100
101
/* -----------------------------------------------------------------------------
102
 * imprementation of the real functions and stuffs.
103
 * -----------------------------------------------------------------------------
104
 */
105
106
SMainLoop *
107
s_main_loop_new () {
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
108
  SMainLoop * self = s_malloc (sizeof (SMainLoop));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
109
116.1.4 by Gustav Hartvigsson
* Removed stupid, non-sense error from SLinkedList.
110
  for (sint i = 0; i < S_MAIN_LOOP_RING_LAST; i++){
111
    for (sint j = 0; j < S_MAIN_LOOP_STATE_LAST; j++){
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
112
      self->mutex[i][j] = s_mutex_new ();
113
    }
114
  }
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
115
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
116
  self->teardown_handler_mutex = s_mutex_new ();
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
117
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
118
  s_mutex_lock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
119
120
  self->ref_count = 1;
121
  self->ring_1_state = S_MAIN_LOOP_STATE_EVENT;
122
  self->ring_2_state = S_MAIN_LOOP_STATE_EVENT;
123
  self->is_run = FALSE;
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
124
125
  self->ring_1_event_handler_list = s_linked_list_new (FREEFUNC (s_free));
126
  self->ring_1_io_push_list = s_linked_list_new (FREEFUNC (s_free));
127
  self->ring_1_io_pull_list = s_linked_list_new (FREEFUNC (s_free));
128
  self->ring_1_workers_list = s_linked_list_new (FREEFUNC (s_free));
129
130
  self->ring_2_event_handler_list = s_linked_list_new (FREEFUNC (s_free));
131
  self->ring_2_io_push_list = s_linked_list_new (FREEFUNC (s_free));
132
  self->ring_2_io_pull_list = s_linked_list_new (FREEFUNC (s_free));
133
  self->ring_2_workers_list = s_linked_list_new (FREEFUNC (s_free));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
134
135
  self->teardown_handler_list = s_linked_list_new (FREEFUNC (_s_main_loop_teardown_handerer_obj_free));
136
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
137
  s_mutex_unlock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
138
139
  return self;
140
}
141
142
SMainLoop *
143
s_main_loop_get_default () {
144
  if (_default_main_loop == NULL) {
145
    _default_main_loop = s_main_loop_new ();
146
  }
147
  return _default_main_loop;
148
}
149
150
void
151
s_main_loop_run (SMainLoop * self) {
152
  assert (self != NULL);
153
  self->is_run = TRUE;
154
  while (self->is_run) {
155
    switch (self->ring_1_state) {
156
      case (S_MAIN_LOOP_STATE_EVENT):
157
        _s_main_loop_do_list (self->ring_1_event_handler_list);
158
        self->ring_1_state = S_MAIN_LOOP_STATE_IO_PUSH;
159
        break;
160
      case (S_MAIN_LOOP_STATE_IO_PUSH):
161
        _s_main_loop_do_list (self->ring_1_io_push_list);
162
        self->ring_1_state = S_MAIN_LOOP_STATE_IO_PULL;
163
        break;
164
      case (S_MAIN_LOOP_STATE_IO_PULL):
165
        _s_main_loop_do_list (self->ring_1_io_pull_list);
166
        self->ring_1_state = S_MAIN_LOOP_STATE_RING_TWO_NEXT;
167
        break;
168
      case (S_MAIN_LOOP_STATE_RING_TWO_NEXT):
169
        _s_main_loop_do_ring_two (self);
170
        self->ring_1_state = S_MAIN_LOOP_STATE_DO_WORKERS;
171
        break;
172
      case (S_MAIN_LOOP_STATE_DO_WORKERS):
173
        _s_main_loop_do_list (self->ring_1_workers_list);
174
        self->ring_1_state = S_MAIN_LOOP_STATE_SLEEP;
175
        break;
176
      case (S_MAIN_LOOP_STATE_SLEEP):
177
        s_usleep (1);
178
        self->ring_1_state = S_MAIN_LOOP_STATE_EVENT;
179
        break;
180
      default:
181
        s_err_print ("Reaching a place that should not be reached.\n"
182
                     "Aborting.");
183
        exit (666);
184
    }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
185
    s_mutex_lock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
186
187
    sint no_of_handlers = 0;
188
189
    no_of_handlers += s_linked_list_len (self->ring_1_event_handler_list);
190
    no_of_handlers += s_linked_list_len (self->ring_1_io_push_list);
191
    no_of_handlers += s_linked_list_len (self->ring_1_io_pull_list);
192
    no_of_handlers += s_linked_list_len (self->ring_1_workers_list);
193
194
    no_of_handlers += s_linked_list_len (self->ring_2_event_handler_list);
195
    no_of_handlers += s_linked_list_len (self->ring_2_io_push_list);
196
    no_of_handlers += s_linked_list_len (self->ring_2_io_pull_list);
197
    no_of_handlers += s_linked_list_len (self->ring_2_workers_list);
198
199
    if (!self->is_run || no_of_handlers == 0) {
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
200
      s_mutex_unlock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
201
      break;
202
    }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
203
    s_mutex_unlock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
204
  }
205
}
206
207
208
void
209
s_main_loop_quit (SMainLoop * self) {
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
210
  s_mutex_lock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
211
  self->is_run = FALSE;
212
213
  s_linked_list_free (self->ring_1_event_handler_list, TRUE);
214
  s_linked_list_free (self->ring_1_io_push_list, TRUE);
215
  s_linked_list_free (self->ring_1_io_pull_list, TRUE);
216
  s_linked_list_free (self->ring_1_workers_list, TRUE);
217
218
  s_linked_list_free (self->ring_2_event_handler_list, TRUE);
219
  s_linked_list_free (self->ring_2_io_push_list, TRUE);
220
  s_linked_list_free (self->ring_2_io_pull_list, TRUE);
221
  s_linked_list_free (self->ring_2_workers_list, TRUE);
222
223
  s_linked_list_free (self->teardown_handler_list, TRUE);
224
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
225
  for (sint i = 0; i < S_MAIN_LOOP_RING_LAST; i++) {
226
    for (sint j = 0; j < S_MAIN_LOOP_STATE_LAST; j++) {
227
      s_print ("[%d][%d]\n",i,j);
228
      s_mutex_free (self->mutex[i][j]);
229
    }
230
  }
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
231
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
232
  s_mutex_free (self->teardown_handler_mutex);
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
233
234
  s_free (self);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
235
}
236
237
void
238
s_main_loop_ref (SMainLoop * self) {
239
  self->ref_count++;
240
}
241
242
void
243
s_main_loop_unref (SMainLoop * self) {
244
  self->ref_count--;
245
}
246
247
void
248
s_main_loop_add_event_handler (SMainLoop * self,
249
                               SMainLoopRing ring,
250
                               RunFunc event_handler,
251
                               spointer user_data) {
252
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
253
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_EVENT]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
254
  if (user_data == NULL) {
255
    s_err_print ("No user data provided to the event handeler."
256
                 " This is an error.");
257
    print_backtrace ();
258
    return;
259
  }
260
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
261
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
262
  item->state = S_MAIN_LOOP_STATE_EVENT;
263
  item->callback = event_handler;
264
  item->user_data = user_data;
265
  item->is_alive = TRUE;
266
267
  switch (ring) {
268
    case (S_MAIN_LOOP_RING_ONE):
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
269
      s_linked_list_append (self->ring_1_event_handler_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
270
      break;
271
    case (S_MAIN_LOOP_RING_TWO):
272
      s_linked_list_append (self->ring_2_event_handler_list, item);
273
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
274
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
275
      s_err_print ("Invalid value of the ring parameter for "
276
                   "s_main_loop_add_io_pull function.");
277
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
278
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_EVENT]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
279
}
280
281
void
282
s_main_loop_add_io_push (SMainLoop * self,
283
                         SMainLoopRing ring,
284
                         RunFunc push_callback,
285
                         spointer user_data) {
286
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
287
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PUSH]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
288
  if (user_data == NULL) {
289
    s_err_print ("No user data provided to the IO push event."
290
                 " This is an error.");
291
    print_backtrace ();
292
    return;
293
  }
294
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
295
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
296
  item->state = S_MAIN_LOOP_STATE_IO_PUSH;
297
  item->callback = push_callback;
298
  item->user_data = user_data;
299
  item->is_alive = TRUE;
300
301
  switch (ring) {
302
    case (S_MAIN_LOOP_RING_ONE):
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
303
      s_linked_list_append (self->ring_1_io_push_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
304
      break;
305
    case (S_MAIN_LOOP_RING_TWO):
306
      s_linked_list_append (self->ring_2_io_push_list, item);
307
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
308
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
309
      s_err_print ("Invalid value of the ring parameter for "
310
                   "s_main_loop_add_io_push function.");
311
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
312
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PUSH]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
313
}
314
315
void
316
s_main_loop_add_io_pull (SMainLoop * self,
317
                         SMainLoopRing ring,
318
                         RunFunc pull_callback,
319
                         spointer user_data) {
320
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
321
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PULL]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
322
  if (user_data == NULL) {
323
    s_err_print ("No user data provided to the IO pull event."
324
                 " This is an error.");
325
    print_backtrace ();
326
    return;
327
  }
328
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
329
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
330
  item->state = S_MAIN_LOOP_STATE_IO_PULL;
331
  item->callback = pull_callback;
332
  item->user_data = user_data;
333
  item->is_alive = TRUE;
334
335
  switch (ring) {
336
    case (S_MAIN_LOOP_RING_ONE):
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
337
      s_linked_list_append (self->ring_1_io_pull_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
338
      break;
339
    case (S_MAIN_LOOP_RING_TWO):
340
      s_linked_list_append (self->ring_2_io_pull_list, item);
341
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
342
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
343
      s_err_print ("Invalid value of the ring parameter for "
344
                   "s_main_loop_add_ function.");
345
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
346
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PULL]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
347
}
348
349
void
350
s_main_loop_add_worker (SMainLoop * self,
351
                        SMainLoopRing ring,
352
                        RunFunc worker_callback,
353
                        spointer user_data) {
354
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
355
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_DO_WORKERS]);
356
  s_dbg_print ("locked");
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
357
358
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
359
  item->state = S_MAIN_LOOP_STATE_DO_WORKERS;
360
  item->callback = worker_callback;
361
  item->user_data = user_data;
362
  item->is_alive = TRUE;
363
364
  switch (ring) {
365
    case (S_MAIN_LOOP_RING_ONE):
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
366
      s_linked_list_append (self->ring_1_workers_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
367
      break;
368
    case (S_MAIN_LOOP_RING_TWO):
369
      s_linked_list_append (self->ring_2_workers_list, item);
370
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
371
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
372
      s_err_print ("Invalid value of the ring parameter for "
373
                   "s_main_loop_add_worker function.");
374
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
375
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_DO_WORKERS]);
376
  s_dbg_print ("Unlocked");
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
377
}
378
379
void
380
s_main_loop_add_teardown_handler (SMainLoop * self,
381
                                  Callback teardown_handler,
382
				                          spointer self_obj,
383
				                          spointer user_data) {
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
384
  s_mutex_lock (self->teardown_handler_mutex);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
385
  if (self == NULL) {
386
    s_err_print ("No self pointer provided for the teardown handler "
387
                 "This is an error.");
388
    print_backtrace ();
389
  }
390
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
391
  SMainLoopTeardownHandler * item = s_malloc (sizeof (SMainLoopTeardownHandler));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
392
393
  item->teardown_handler = teardown_handler;
394
  item->obj_self = self_obj;
395
  item->user_data = user_data;
396
397
  s_linked_list_append (self->teardown_handler_list, item);
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
398
  s_mutex_unlock (self->teardown_handler_mutex);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
399
}
400
401
/* ************************************************************************** */
402
403
void
404
_s_main_loop_teardown_handerer_obj_free (SMainLoopTeardownHandler * self) {
405
  Callback callback = self->teardown_handler;
406
  callback (self->obj_self, self->user_data);
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
407
  s_free (self);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
408
}
409
410
void
411
_s_main_loop_do_list (SLinkedList * event_handler_list) {
412
  if (s_linked_list_len (event_handler_list) == 0) {
413
    return;
414
  }
415
416
  s_linked_list_head (event_handler_list);
417
  do {
418
    SMainLoopItem * item = s_linked_list_get_current (event_handler_list);
419
    RunFunc callback = item->callback;
420
    spointer user_data = item->user_data;
421
422
    item->is_alive  = callback (user_data);
423
  } while (s_linked_list_next (event_handler_list));
424
425
  s_linked_list_head (event_handler_list);
426
  do {
427
    SMainLoopItem * item = s_linked_list_get_current (event_handler_list);
428
    if (!item->is_alive) {
429
      s_linked_list_remove_current (event_handler_list, TRUE);
430
    }
431
  } while (s_linked_list_next (event_handler_list));
432
433
}
434
435
void
436
_s_main_loop_do_ring_two (SMainLoop * self) {
437
  switch (self->ring_2_state) {
438
    case (S_MAIN_LOOP_STATE_EVENT):
439
      _s_main_loop_do_list (self->ring_2_event_handler_list);
440
      self->ring_2_state = S_MAIN_LOOP_STATE_IO_PUSH;
441
      break;
442
    case (S_MAIN_LOOP_STATE_IO_PUSH):
443
      _s_main_loop_do_list (self->ring_2_io_push_list);
444
      self->ring_2_state = S_MAIN_LOOP_STATE_IO_PULL;
445
      break;
446
    case (S_MAIN_LOOP_STATE_IO_PULL):
447
      _s_main_loop_do_list (self->ring_2_io_pull_list);
448
      self->ring_2_state = S_MAIN_LOOP_STATE_DO_WORKERS;
449
      break;
450
    case (S_MAIN_LOOP_STATE_DO_WORKERS):
451
      _s_main_loop_do_list (self->ring_2_workers_list);
452
      self->ring_2_state = S_MAIN_LOOP_STATE_EVENT;
453
      break;
454
    default:
455
      s_err_print ("Reaching a place that should not be reached.\n"
456
                   "Aborting.");
457
      exit (666);
458
  }
459
}
460
461