int ast_sched_runq(struct sched_context *con) { /* * Launch all events which need to be run at this time. */ struct sched *current; struct timeval tv; int x=0; int res; DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n")); ast_mutex_lock(&con->lock); tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000)); for(;;) { if (!con->schedq) break; /* schedule all events which are going to expire within 1ms. * We only care about millisecond accuracy anyway, so this will * help us get more than one event at one time if they are very * close together. */ if (SOONER(con->schedq->when, tv)) { current = con->schedq; con->schedq = con->schedq->next; con->schedcnt--; /* * At this point, the schedule queue is still intact. We * have removed the first event and the rest is still there, * so it's permissible for the callback to add new events, but * trying to delete itself won't work because it isn't in * the schedule queue. If that's what it wants to do, it * should return 0. */ ast_mutex_unlock(&con->lock); res = current->callback(current->data); ast_mutex_lock(&con->lock); if (res) { /* * If they return non-zero, we should schedule them to be * run again. */ if (sched_settime(¤t->when, current->variable? res : current->resched)) { sched_release(con, current); } else schedule(con, current); } else { /* No longer needed, so release it */ sched_release(con, current); } x++; } else break; } ast_mutex_unlock(&con->lock); return x; }
static void schedule(struct sched_context *con, struct sched *s) { /* * Take a sched structure and put it in the * queue, such that the soonest event is * first in the list. */ struct sched *last=NULL; struct sched *current=con->schedq; while(current) { if (SOONER(s->when, current->when)) break; last = current; current = current->next; } /* Insert this event into the schedule */ s->next = current; if (last) last->next = s; else con->schedq = s; con->schedcnt++; if (!last && !pthread_equal(con->tid, CW_PTHREADT_NULL)) cw_cond_signal(&con->service); }
int cw_sched_runq(struct sched_context *con) { /* * Launch all events which need to be run at this time. */ struct sched *runq, **endq, *current; struct timeval tv; int x=0; int res; #ifdef DEBUG_SCHED DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_runq()\n")); #endif cw_mutex_lock(&con->lock); /* schedule all events which are going to expire within 1ms. * We only care about millisecond accuracy anyway, so this will * help us get more than one event at one time if they are very * close together. */ tv = cw_tvadd(cw_tvnow(), cw_tv(0, 1000)); runq = con->schedq; endq = &runq; while (con->schedq && SOONER(con->schedq->when, tv)) { endq = &con->schedq->next; con->schedq = con->schedq->next; con->schedcnt--; } *endq = NULL; cw_mutex_unlock(&con->lock); while ((current = runq)) { runq = runq->next; x++; res = current->callback(current->data); if (res) { /* * If they return non-zero, we should schedule them to be * run again. */ current->when = cw_tvadd(current->when, cw_samp2tv((current->variable ? res : current->resched), 1000)); schedule(con, current); } else { /* No longer needed, so release it */ sched_release(con, current); } } return x; }
static void schedule(struct sched_context *con, struct sched *s) { /* * Take a sched structure and put it in the * queue, such that the soonest event is * first in the list. */ struct sched *last=NULL; struct sched *current=con->schedq; while(current) { if (SOONER(s->when, current->when)) break; last = current; current = current->next; } /* Insert this event into the schedule */ s->next = current; if (last) last->next = s; else con->schedq = s; con->schedcnt++; }