/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
  }
211
}
212
213
214
void
215
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.
216
  s_mutex_lock (self->mutex[S_MAIN_LOOP_RING_NONE][S_MAIN_LOOP_STATE_NONE]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
217
  self->is_run = FALSE;
218
219
  s_linked_list_free (self->ring_1_event_handler_list, TRUE);
220
  s_linked_list_free (self->ring_1_io_push_list, TRUE);
221
  s_linked_list_free (self->ring_1_io_pull_list, TRUE);
222
  s_linked_list_free (self->ring_1_workers_list, TRUE);
223
224
  s_linked_list_free (self->ring_2_event_handler_list, TRUE);
225
  s_linked_list_free (self->ring_2_io_push_list, TRUE);
226
  s_linked_list_free (self->ring_2_io_pull_list, TRUE);
227
  s_linked_list_free (self->ring_2_workers_list, TRUE);
228
229
  s_linked_list_free (self->teardown_handler_list, TRUE);
230
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
231
  for (sint i = 0; i < S_MAIN_LOOP_RING_LAST; i++) {
232
    for (sint j = 0; j < S_MAIN_LOOP_STATE_LAST; j++) {
233
      s_print ("[%d][%d]\n",i,j);
234
      s_mutex_free (self->mutex[i][j]);
235
    }
236
  }
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
237
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
238
  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.
239
240
  s_free (self);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
241
}
242
243
void
244
s_main_loop_ref (SMainLoop * self) {
245
  self->ref_count++;
246
}
247
248
void
249
s_main_loop_unref (SMainLoop * self) {
250
  self->ref_count--;
251
}
252
253
void
254
s_main_loop_add_event_handler (SMainLoop * self,
255
                               SMainLoopRing ring,
256
                               RunFunc event_handler,
257
                               spointer user_data) {
258
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
259
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_EVENT]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
260
  if (user_data == NULL) {
261
    s_err_print ("No user data provided to the event handeler."
262
                 " This is an error.");
263
    print_backtrace ();
264
    return;
265
  }
266
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
267
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
268
  item->state = S_MAIN_LOOP_STATE_EVENT;
269
  item->callback = event_handler;
270
  item->user_data = user_data;
271
  item->is_alive = TRUE;
272
273
  switch (ring) {
274
    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.
275
      s_linked_list_append (self->ring_1_event_handler_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
276
      break;
277
    case (S_MAIN_LOOP_RING_TWO):
278
      s_linked_list_append (self->ring_2_event_handler_list, item);
279
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
280
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
281
      s_err_print ("Invalid value of the ring parameter for "
282
                   "s_main_loop_add_io_pull function.");
283
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
284
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_EVENT]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
285
}
286
287
void
288
s_main_loop_add_io_push (SMainLoop * self,
289
                         SMainLoopRing ring,
290
                         RunFunc push_callback,
291
                         spointer user_data) {
292
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
293
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PUSH]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
294
  if (user_data == NULL) {
295
    s_err_print ("No user data provided to the IO push event."
296
                 " This is an error.");
297
    print_backtrace ();
298
    return;
299
  }
300
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
301
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
302
  item->state = S_MAIN_LOOP_STATE_IO_PUSH;
303
  item->callback = push_callback;
304
  item->user_data = user_data;
305
  item->is_alive = TRUE;
306
307
  switch (ring) {
308
    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.
309
      s_linked_list_append (self->ring_1_io_push_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
310
      break;
311
    case (S_MAIN_LOOP_RING_TWO):
312
      s_linked_list_append (self->ring_2_io_push_list, item);
313
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
314
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
315
      s_err_print ("Invalid value of the ring parameter for "
316
                   "s_main_loop_add_io_push function.");
317
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
318
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PUSH]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
319
}
320
321
void
322
s_main_loop_add_io_pull (SMainLoop * self,
323
                         SMainLoopRing ring,
324
                         RunFunc pull_callback,
325
                         spointer user_data) {
326
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
327
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PULL]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
328
  if (user_data == NULL) {
329
    s_err_print ("No user data provided to the IO pull event."
330
                 " This is an error.");
331
    print_backtrace ();
332
    return;
333
  }
334
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
335
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
336
  item->state = S_MAIN_LOOP_STATE_IO_PULL;
337
  item->callback = pull_callback;
338
  item->user_data = user_data;
339
  item->is_alive = TRUE;
340
341
  switch (ring) {
342
    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.
343
      s_linked_list_append (self->ring_1_io_pull_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
344
      break;
345
    case (S_MAIN_LOOP_RING_TWO):
346
      s_linked_list_append (self->ring_2_io_pull_list, item);
347
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
348
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
349
      s_err_print ("Invalid value of the ring parameter for "
350
                   "s_main_loop_add_ function.");
351
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
352
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_IO_PULL]);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
353
}
354
355
void
356
s_main_loop_add_worker (SMainLoop * self,
357
                        SMainLoopRing ring,
358
                        RunFunc worker_callback,
359
                        spointer user_data) {
360
  //
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
361
  s_mutex_lock (self->mutex[ring][S_MAIN_LOOP_STATE_DO_WORKERS]);
362
  s_dbg_print ("locked");
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
363
364
  SMainLoopItem * item = s_malloc (sizeof (SMainLoopItem));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
365
  item->state = S_MAIN_LOOP_STATE_DO_WORKERS;
366
  item->callback = worker_callback;
367
  item->user_data = user_data;
368
  item->is_alive = TRUE;
369
370
  switch (ring) {
371
    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.
372
      s_linked_list_append (self->ring_1_workers_list, item);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
373
      break;
374
    case (S_MAIN_LOOP_RING_TWO):
375
      s_linked_list_append (self->ring_2_workers_list, item);
376
      break;
116.1.2 by Gustav Hartvigsson
* added a build (build.sh)script that later can be used for other things.
377
    default:
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
378
      s_err_print ("Invalid value of the ring parameter for "
379
                   "s_main_loop_add_worker function.");
380
  }
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
381
  s_mutex_unlock (self->mutex[ring][S_MAIN_LOOP_STATE_DO_WORKERS]);
382
  s_dbg_print ("Unlocked");
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
383
}
384
385
void
386
s_main_loop_add_teardown_handler (SMainLoop * self,
387
                                  Callback teardown_handler,
388
				                          spointer self_obj,
389
				                          spointer user_data) {
116.1.3 by Gustav Hartvigsson
* Something wring with the STherad... Will have to re-implement the whole thing.
390
  s_mutex_lock (self->teardown_handler_mutex);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
391
  if (self == NULL) {
392
    s_err_print ("No self pointer provided for the teardown handler "
393
                 "This is an error.");
394
    print_backtrace ();
395
  }
396
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
397
  SMainLoopTeardownHandler * item = s_malloc (sizeof (SMainLoopTeardownHandler));
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
398
399
  item->teardown_handler = teardown_handler;
400
  item->obj_self = self_obj;
401
  item->user_data = user_data;
402
403
  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.
404
  s_mutex_unlock (self->teardown_handler_mutex);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
405
}
406
407
/* ************************************************************************** */
408
409
void
410
_s_main_loop_teardown_handerer_obj_free (SMainLoopTeardownHandler * self) {
411
  Callback callback = self->teardown_handler;
412
  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.
413
  s_free (self);
116.1.1 by Gustav Hartvigsson
* Implemented the SMainLoop
414
}
415
416
void
417
_s_main_loop_do_list (SLinkedList * event_handler_list) {
418
  if (s_linked_list_len (event_handler_list) == 0) {
419
    return;
420
  }
421
422
  s_linked_list_head (event_handler_list);
423
  do {
424
    SMainLoopItem * item = s_linked_list_get_current (event_handler_list);
425
    RunFunc callback = item->callback;
426
    spointer user_data = item->user_data;
427
428
    item->is_alive  = callback (user_data);
429
  } while (s_linked_list_next (event_handler_list));
430
431
  s_linked_list_head (event_handler_list);
432
  do {
433
    SMainLoopItem * item = s_linked_list_get_current (event_handler_list);
434
    if (!item->is_alive) {
435
      s_linked_list_remove_current (event_handler_list, TRUE);
436
    }
437
  } while (s_linked_list_next (event_handler_list));
438
439
}
440
441
void
442
_s_main_loop_do_ring_two (SMainLoop * self) {
443
  switch (self->ring_2_state) {
444
    case (S_MAIN_LOOP_STATE_EVENT):
445
      _s_main_loop_do_list (self->ring_2_event_handler_list);
446
      self->ring_2_state = S_MAIN_LOOP_STATE_IO_PUSH;
447
      break;
448
    case (S_MAIN_LOOP_STATE_IO_PUSH):
449
      _s_main_loop_do_list (self->ring_2_io_push_list);
450
      self->ring_2_state = S_MAIN_LOOP_STATE_IO_PULL;
451
      break;
452
    case (S_MAIN_LOOP_STATE_IO_PULL):
453
      _s_main_loop_do_list (self->ring_2_io_pull_list);
454
      self->ring_2_state = S_MAIN_LOOP_STATE_DO_WORKERS;
455
      break;
456
    case (S_MAIN_LOOP_STATE_DO_WORKERS):
457
      _s_main_loop_do_list (self->ring_2_workers_list);
458
      self->ring_2_state = S_MAIN_LOOP_STATE_EVENT;
459
      break;
460
    default:
461
      s_err_print ("Reaching a place that should not be reached.\n"
462
                   "Aborting.");
463
      exit (666);
464
  }
465
}
466
467