44
48
/* Add a new thread to the list. */
46
thread_list_add(thread_list * list, thread * thread)
50
thread_list_add(thread_list * list, thread * thread_obj)
49
thread->prev = list->tail;
52
thread_obj->next = NULL;
53
thread_obj->prev = list->tail;
51
list->tail->next = thread;
55
list->tail->next = thread_obj;
57
list->head = thread_obj;
58
list->tail = thread_obj;
58
62
/* Add a new thread to the list. */
60
thread_list_add_before(thread_list * list, thread * point, thread * thread)
64
thread_list_add_before(thread_list * list, thread * point, thread * thread_obj)
63
thread->prev = point->prev;
66
thread_obj->next = point;
67
thread_obj->prev = point->prev;
65
point->prev->next = thread;
69
point->prev->next = thread_obj;
71
list->head = thread_obj;
72
point->prev = thread_obj;
72
76
/* Add a thread in the list sorted by timeval */
74
thread_list_add_timeval(thread_list * list, thread * thread)
78
thread_list_add_timeval(thread_list * list, thread * thread_obj)
76
80
struct _thread *tt;
78
82
for (tt = list->head; tt; tt = tt->next) {
79
if (timer_cmp(thread->sands, tt->sands) <= 0)
83
if (timer_cmp(thread_obj->sands, tt->sands) <= 0)
84
thread_list_add_before(list, tt, thread);
88
thread_list_add_before(list, tt, thread_obj);
86
thread_list_add(list, thread);
90
thread_list_add(list, thread_obj);
89
93
/* Delete a thread from the list. */
91
thread_list_delete(thread_list * list, thread * thread)
95
thread_list_delete(thread_list * list, thread * thread_obj)
94
thread->next->prev = thread->prev;
96
list->tail = thread->prev;
98
thread->prev->next = thread->next;
100
list->head = thread->next;
101
thread->next = thread->prev = NULL;
98
thread_obj->next->prev = thread_obj->prev;
100
list->tail = thread_obj->prev;
101
if (thread_obj->prev)
102
thread_obj->prev->next = thread_obj->next;
104
list->head = thread_obj->next;
105
thread_obj->next = thread_obj->prev = NULL;
106
110
/* Free all unused thread. */
108
112
thread_clean_unuse(thread_master * m)
112
thread = m->unuse.head;
116
thread_obj = m->unuse.head;
114
118
struct _thread *t;
121
thread_obj = t->next;
119
123
thread_list_delete(&m->unuse, t);
127
131
/* Move thread to unuse list. */
129
thread_add_unuse(thread_master * m, thread * thread)
133
thread_add_unuse(thread_master * m, thread * thread_obj)
131
135
assert(m != NULL);
132
assert(thread->next == NULL);
133
assert(thread->prev == NULL);
134
assert(thread->type == THREAD_UNUSED);
135
thread_list_add(&m->unuse, thread);
136
assert(thread_obj->next == NULL);
137
assert(thread_obj->prev == NULL);
138
assert(thread_obj->type == THREAD_UNUSED);
139
thread_list_add(&m->unuse, thread_obj);
138
142
/* Move list element to unuse queue */
140
thread_destroy_list(thread_master * m, thread_list thread_list)
144
thread_destroy_list(thread_master * m, thread_list thread_list_obj)
144
thread = thread_list.head;
148
thread_obj = thread_list_obj.head;
147
151
struct _thread *t;
154
thread_obj = t->next;
152
thread_list_delete(&thread_list, t);
156
thread_list_delete(&thread_list_obj, t);
153
157
t->type = THREAD_UNUSED;
154
158
thread_add_unuse(m, t);
227
thread = thread_new(m);
228
thread->type = THREAD_READ;
231
thread_obj = thread_new(m);
232
thread_obj->type = THREAD_READ;
234
thread_obj->master = m;
235
thread_obj->func = func;
236
thread_obj->arg = arg;
233
237
FD_SET(fd, &m->readfd);
238
thread_obj->u.fd = fd;
236
240
/* Compute read timeout value */
238
thread->sands = timer_add_long(time_now, timer);
242
thread_obj->sands = timer_add_long(time_now, timer);
240
244
/* Sort the thread. */
241
thread_list_add_timeval(&m->read, thread);
245
thread_list_add_timeval(&m->read, thread_obj);
246
250
/* Add new write thread. */
260
thread = thread_new(m);
261
thread->type = THREAD_WRITE;
264
thread_obj = thread_new(m);
265
thread_obj->type = THREAD_WRITE;
267
thread_obj->master = m;
268
thread_obj->func = func;
269
thread_obj->arg = arg;
266
270
FD_SET(fd, &m->writefd);
271
thread_obj->u.fd = fd;
269
273
/* Compute write timeout value */
271
thread->sands = timer_add_long(time_now, timer);
275
thread_obj->sands = timer_add_long(time_now, timer);
273
277
/* Sort the thread. */
274
thread_list_add_timeval(&m->write, thread);
278
thread_list_add_timeval(&m->write, thread_obj);
279
283
/* Add timer event thread. */
281
285
thread_add_timer(thread_master * m, int (*func) (thread *)
282
286
, void *arg, long timer)
286
290
assert(m != NULL);
288
thread = thread_new(m);
289
thread->type = THREAD_TIMER;
292
thread_obj = thread_new(m);
293
thread_obj->type = THREAD_TIMER;
295
thread_obj->master = m;
296
thread_obj->func = func;
297
thread_obj->arg = arg;
295
299
/* Do we need jitter here? */
297
thread->sands = timer_add_long(time_now, timer);
301
thread_obj->sands = timer_add_long(time_now, timer);
299
303
/* Sort by timeval. */
300
thread_list_add_timeval(&m->timer, thread);
304
thread_list_add_timeval(&m->timer, thread_obj);
305
309
/* Add a child thread. */
307
311
thread_add_child(thread_master * m, int (*func) (thread *)
308
312
, void * arg, pid_t pid, long timer)
312
316
assert(m != NULL);
314
thread = thread_new(m);
315
thread->type = THREAD_CHILD;
320
thread->u.c.pid = pid;
321
thread->u.c.status = 0;
318
thread_obj = thread_new(m);
319
thread_obj->type = THREAD_CHILD;
321
thread_obj->master = m;
322
thread_obj->func = func;
323
thread_obj->arg = arg;
324
thread_obj->u.c.pid = pid;
325
thread_obj->u.c.status = 0;
323
327
/* Compute write timeout value */
325
thread->sands = timer_add_long(time_now, timer);
329
thread_obj->sands = timer_add_long(time_now, timer);
327
331
/* Sort by timeval. */
328
thread_list_add_timeval(&m->child, thread);
332
thread_list_add_timeval(&m->child, thread_obj);
333
337
/* Add simple event thread. */
335
339
thread_add_event(thread_master * m, int (*func) (thread *)
336
340
, void *arg, int val)
340
344
assert(m != NULL);
342
thread = thread_new(m);
343
thread->type = THREAD_EVENT;
349
thread_list_add(&m->event, thread);
346
thread_obj = thread_new(m);
347
thread_obj->type = THREAD_EVENT;
349
thread_obj->master = m;
350
thread_obj->func = func;
351
thread_obj->arg = arg;
352
thread_obj->u.val = val;
353
thread_list_add(&m->event, thread_obj);
354
358
/* Add simple event thread. */
356
360
thread_add_terminate_event(thread_master * m)
360
364
assert(m != NULL);
362
thread = thread_new(m);
363
thread->type = THREAD_TERMINATE;
369
thread_list_add(&m->event, thread);
366
thread_obj = thread_new(m);
367
thread_obj->type = THREAD_TERMINATE;
369
thread_obj->master = m;
370
thread_obj->func = NULL;
371
thread_obj->arg = NULL;
372
thread_obj->u.val = 0;
373
thread_list_add(&m->event, thread_obj);
374
378
/* Cancel thread from scheduler. */
376
thread_cancel(thread * thread)
380
thread_cancel(thread * thread_obj)
378
switch (thread->type) {
382
switch (thread_obj->type) {
379
383
case THREAD_READ:
380
assert(FD_ISSET(thread->u.fd, &thread->master->readfd));
381
FD_CLR(thread->u.fd, &thread->master->readfd);
382
thread_list_delete(&thread->master->read, thread);
384
assert(FD_ISSET(thread_obj->u.fd, &thread_obj->master->readfd));
385
FD_CLR(thread_obj->u.fd, &thread_obj->master->readfd);
386
thread_list_delete(&thread_obj->master->read, thread_obj);
384
388
case THREAD_WRITE:
385
assert(FD_ISSET(thread->u.fd, &thread->master->writefd));
386
FD_CLR(thread->u.fd, &thread->master->writefd);
387
thread_list_delete(&thread->master->write, thread);
389
assert(FD_ISSET(thread_obj->u.fd, &thread_obj->master->writefd));
390
FD_CLR(thread_obj->u.fd, &thread_obj->master->writefd);
391
thread_list_delete(&thread_obj->master->write, thread_obj);
389
393
case THREAD_TIMER:
390
thread_list_delete(&thread->master->timer, thread);
394
thread_list_delete(&thread_obj->master->timer, thread_obj);
392
396
case THREAD_CHILD:
393
397
/* Does this need to kill the child, or is that the
395
399
* This function is currently unused, so leave it for now.
397
thread_list_delete(&thread->master->child, thread);
401
thread_list_delete(&thread_obj->master->child, thread_obj);
399
403
case THREAD_EVENT:
400
thread_list_delete(&thread->master->event, thread);
404
thread_list_delete(&thread_obj->master->event, thread_obj);
402
406
case THREAD_READY:
403
thread_list_delete(&thread->master->ready, thread);
407
thread_list_delete(&thread_obj->master->ready, thread_obj);
409
thread->type = THREAD_UNUSED;
410
thread_add_unuse(thread->master, thread);
413
thread_obj->type = THREAD_UNUSED;
414
thread_add_unuse(thread_obj->master, thread_obj);
413
417
/* Delete all events which has argument value arg. */
415
419
thread_cancel_event(thread_master * m, void *arg)
419
thread = m->event.head;
423
thread_obj = m->event.head;
421
425
struct _thread *t;
428
thread_obj = t->next;
426
430
if (t->arg == arg) {
427
431
thread_list_delete(&m->event, t);
506
508
sigemptyset(&block_sigset);
507
509
sigaddset(&block_sigset, SIGCHLD);
509
/* Timer allocation */
510
timer_wait = (TIMEVAL *) MALLOC(sizeof (TIMEVAL));
511
/* Timer initialization */
512
memset(&timer_wait, 0, sizeof (TIMEVAL));
512
514
retry: /* When thread can't fetch try to find next thread again. */
514
516
/* If there is event process it first. */
515
while ((thread = thread_trim_head(&m->event))) {
517
FREE_PTR(timer_wait);
517
while ((thread_obj = thread_trim_head(&m->event))) {
518
*fetch = *thread_obj;
519
520
/* If daemon hanging event is received return NULL pointer */
520
if (thread->type == THREAD_TERMINATE) {
521
thread->type = THREAD_UNUSED;
522
thread_add_unuse(m, thread);
521
if (thread_obj->type == THREAD_TERMINATE) {
522
thread_obj->type = THREAD_UNUSED;
523
thread_add_unuse(m, thread_obj);
525
thread->type = THREAD_UNUSED;
526
thread_add_unuse(m, thread);
526
thread_obj->type = THREAD_UNUSED;
527
thread_add_unuse(m, thread_obj);
530
531
/* If there is ready threads process them */
531
while ((thread = thread_trim_head(&m->ready))) {
533
thread->type = THREAD_UNUSED;
534
thread_add_unuse(m, thread);
535
FREE_PTR(timer_wait);
532
while ((thread_obj = thread_trim_head(&m->ready))) {
533
*fetch = *thread_obj;
534
thread_obj->type = THREAD_UNUSED;
535
thread_add_unuse(m, thread_obj);
571
571
/* Emulate pselect */
572
572
sigset_t saveset;
573
573
sigprocmask(SIG_SETMASK, &sigset, &saveset);
574
ret = select(FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
574
ret = select(FD_SETSIZE, &readfd, &writefd, &exceptfd,
575
(TIMER_ISNULL(timer_wait)) ? NULL : &timer_wait);
575
576
sigprocmask(SIG_SETMASK, &saveset, NULL);
580
* When we receive a signal, we only add it to the signal_mask. This
581
* is so that we can run our handler functions in a safe place and
582
* not in, for example, the middle of a list modification.
584
if (signal_pending())
585
signal_run_callback();
578
587
/* Update current time */
721
729
/* Call thread ! */
723
thread_call(thread * thread)
731
thread_call(thread * thread_obj)
725
thread->id = thread_get_id();
726
(*thread->func) (thread);
733
thread_obj->id = thread_get_id();
734
(*thread_obj->func) (thread_obj);
729
737
/* Our infinite scheduling loop */
730
extern thread_master *master;
731
extern unsigned int debug;
733
739
launch_scheduler(void)
738
744
* Processing the master thread queues,
739
745
* return and execute one ready thread.
741
while (thread_fetch(master, &thread)) {
747
while (thread_fetch(master, &thread_obj)) {
742
748
/* Run until error, used for debuging only */
744
750
if ((debug & 520) == 520) {