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