static void* mevent_start_base_entry(void *arg) { int rv; struct timespec ts; struct queue_entry *q; struct event_entry *e = (struct event_entry*)arg; int *mypos = _tls_get_mypos(); *mypos = e->cur_thread; mtc_dbg("I'm %s %dnd thread", e->name, *mypos); for (;;) { /* Condition waits are specified with absolute timeouts, see * pthread_cond_timedwait()'s SUSv3 specification for more * information. We need to calculate it each time. * We sleep for 1 sec. There's no real need for it to be too * fast (it's only used so that stop detection doesn't take * long), but we don't want it to be too slow either. */ mutil_utc_time(&ts); ts.tv_sec += 1; rv = 0; queue_lock(e->op_queue[*mypos]); while (queue_isempty(e->op_queue[*mypos]) && rv == 0) { rv = queue_timedwait(e->op_queue[*mypos], &ts); } if (rv != 0 && rv != ETIMEDOUT) { errlog("Error in queue_timedwait()"); /* When the timedwait fails the lock is released, so * we need to properly annotate this case. */ __release(e->op_queue[*mypos]->lock); continue; } q = queue_get(e->op_queue[*mypos]); queue_unlock(e->op_queue[*mypos]); if (q == NULL) { if (e->loop_should_stop) { break; } else { continue; } } mtc_dbg("%s %d process", e->name, *mypos); e->process_driver(e, q, *mypos); /* Free the entry that was allocated when tipc queued the * operation. This also frees it's components. */ queue_entry_free(q); } return NULL; }
static void* event_thread(void *data) { QUEUE* event_q = (QUEUE*) data; parrot_event* event; QUEUE_ENTRY *entry; int running = 1; LOCK(event_q->queue_mutex); /* * we might already have an event in the queue */ if (peek_entry(event_q)) running = process_events(event_q); while (running) { entry = peek_entry(event_q); if (!entry) { /* wait infinite until entry arrives */ queue_wait(event_q); } else if (entry->type == QUEUE_ENTRY_TYPE_TIMED_EVENT) { /* do a_timedwait for entry */ struct timespec abs_time; FLOATVAL when; event = (parrot_event* )entry->data; when = event->u.timer_event.abs_time; abs_time.tv_sec = (time_t) when; abs_time.tv_nsec = (when - abs_time.tv_sec) * (1000L*1000L*1000L); queue_timedwait(event_q, &abs_time); } else { /* we shouldn't get here probably */ internal_exception(1, "Spurious event"); } /* * one or more entries arrived - we hold the mutex again * so we have to use the nonsync_pop_entry to pop off event entries */ running = process_events(event_q); } /* event loop */ /* * the main interpreter is dying * TODO empty the queue */ UNLOCK(event_q->queue_mutex); queue_destroy(event_q); stop_io_thread(); edebug((stderr, "event thread stopped\n")); return NULL; }