Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sched.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/sched.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/lock.h>

Go to the source code of this file.

Defines

#define DEBUG(a)
#define SOONER(a, b)

Functions

sched_contextsched_context_create (void)
 New schedule context.
void sched_context_destroy (struct sched_context *con)
 destroys a schedule context
int ast_sched_wait (struct sched_context *con)
 Determines number of seconds until the next outstanding event to take place.
int ast_sched_add (struct sched_context *con, int when, ast_sched_cb callback, void *data)
 Adds a scheduled event.
int ast_sched_del (struct sched_context *con, int id)
 Deletes a scheduled event.
void ast_sched_dump (struct sched_context *con)
 Dumps the scheduler contents.
int ast_sched_runq (struct sched_context *con)
 Runs the queue.


Define Documentation

#define DEBUG  ) 
 

Definition at line 17 of file sched.c.

#define SOONER a,
 ) 
 

Value:

(((b).tv_sec > (a).tv_sec) || \
                (((b).tv_sec == (a).tv_sec) && ((b).tv_usec > (a).tv_usec)))

Definition at line 32 of file sched.c.

Referenced by ast_sched_runq().


Function Documentation

int ast_sched_add struct sched_context con,
int  when,
ast_sched_cb  callback,
void *  data
 

Adds a scheduled event.

Parameters:
con Schduler context to add
when how many milliseconds to wait for event to occur
callback function to call when the amount of time expires
data data to pass to the callback Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) Returns 0 on success, -1 on failure

Definition at line 232 of file sched.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, sched::callback, sched::data, DEBUG, sched::id, LOG_DEBUG, LOG_NOTICE, sched::resched, and sched::when.

00233 {
00234    /*
00235     * Schedule callback(data) to happen when ms into the future
00236     */
00237    struct sched *tmp;
00238    int res = -1;
00239    DEBUG(ast_log(LOG_DEBUG, "ast_sched_add()\n"));
00240    if (!when) {
00241       ast_log(LOG_NOTICE, "Scheduled event in 0 ms?\n");
00242       return -1;
00243    }
00244    ast_mutex_lock(&con->lock);
00245    if ((tmp = sched_alloc(con))) {
00246       tmp->id = con->eventcnt++;
00247       tmp->callback = callback;
00248       tmp->data = data;
00249       tmp->resched = when;
00250       tmp->when.tv_sec = 0;
00251       tmp->when.tv_usec = 0;
00252       if (sched_settime(&tmp->when, when)) {
00253          sched_release(con, tmp);
00254       } else {
00255          schedule(con, tmp);
00256          res = tmp->id;
00257       }
00258    }
00259    ast_mutex_unlock(&con->lock);
00260    return res;
00261 }

int ast_sched_del struct sched_context con,
int  id
 

Deletes a scheduled event.

Parameters:
con scheduling context to delete item from
id ID of the scheduled item to delete Remove this event from being run. A procedure should not remove its own event, but return 0 instead. Returns 0 on success, -1 on failure

Definition at line 263 of file sched.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, CRASH, DEBUG, LOG_DEBUG, LOG_NOTICE, sched::next, and s.

Referenced by ast_closestream().

00264 {
00265    /*
00266     * Delete the schedule entry with number
00267     * "id".  It's nearly impossible that there
00268     * would be two or more in the list with that
00269     * id.
00270     */
00271    struct sched *last=NULL, *s;
00272    DEBUG(ast_log(LOG_DEBUG, "ast_sched_del()\n"));
00273    ast_mutex_lock(&con->lock);
00274    s = con->schedq;
00275    while(s) {
00276       if (s->id == id) {
00277          if (last)
00278             last->next = s->next;
00279          else
00280             con->schedq = s->next;
00281          con->schedcnt--;
00282          sched_release(con, s);
00283          break;
00284       }
00285       last = s;
00286       s = s->next;
00287    }
00288    ast_mutex_unlock(&con->lock);
00289    if (!s) {
00290       ast_log(LOG_NOTICE, "Attempted to delete non-existant schedule entry %d!\n", id);
00291 #ifdef DO_CRASH
00292       CRASH;
00293 #endif
00294       return -1;
00295    } else
00296       return 0;
00297 }

void ast_sched_dump struct sched_context con  ) 
 

Dumps the scheduler contents.

Parameters:
con Context to dump Debugging: Dump the contents of the scheduler to stderr

Definition at line 299 of file sched.c.

References ast_log(), sched::callback, sched::data, sched::id, LOG_DEBUG, sched::next, s, and sched::when.

00300 {
00301    /*
00302     * Dump the contents of the scheduler to
00303     * stderr
00304     */
00305    struct sched *q;
00306    struct timeval tv;
00307    time_t s, ms;
00308    gettimeofday(&tv, NULL);
00309 #ifdef SCHED_MAX_CACHE
00310    ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", 
00311                      con-> schedcnt, con->eventcnt - 1, con->schedccnt);
00312 #else
00313    ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total)\n",
00314                      con-> schedcnt, con->eventcnt - 1);
00315 #endif
00316 
00317    ast_log(LOG_DEBUG, "=================================================\n");
00318    ast_log(LOG_DEBUG, "|ID    Callback    Data        Time  (sec:ms)   |\n");
00319    ast_log(LOG_DEBUG, "+-----+-----------+-----------+-----------------+\n");
00320    q = con->schedq;
00321    while(q) {
00322       s =  q->when.tv_sec - tv.tv_sec;
00323       ms = q->when.tv_usec - tv.tv_usec;
00324       if (ms < 0) {
00325          ms += 1000000;
00326          s--;
00327       }
00328       ast_log(LOG_DEBUG, "|%.4d | %p | %p | %.6ld : %.6ld |\n", 
00329             q->id,
00330             q->callback,
00331             q->data,
00332             (long)s,
00333             (long)ms);
00334       q=q->next;
00335    }
00336    ast_log(LOG_DEBUG, "=================================================\n");
00337    
00338 }

int ast_sched_runq struct sched_context con  ) 
 

Runs the queue.

Parameters:
con Scheduling context to run Run the queue, executing all callbacks which need to be performed at this time. Returns the number of events processed.

Definition at line 340 of file sched.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, sched::callback, sched::data, DEBUG, LOG_DEBUG, LOG_NOTICE, sched::next, sched::resched, SOONER, and sched::when.

00341 {
00342    /*
00343     * Launch all events which need to be run at this time.
00344     */
00345    struct sched *current;
00346    struct timeval tv;
00347    int x=0;
00348    int res;
00349    DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n"));
00350       
00351    ast_mutex_lock(&con->lock);
00352    for(;;) {
00353       if (!con->schedq)
00354          break;
00355       if (gettimeofday(&tv, NULL)) {
00356          /* This should never happen */
00357          ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
00358          break;
00359       }
00360       /* We only care about millisecond accuracy anyway, so this will
00361          help us get more than one event at one time if they are very
00362          close together. */
00363       tv.tv_usec += 1000;
00364       if (SOONER(con->schedq->when, tv)) {
00365          current = con->schedq;
00366          con->schedq = con->schedq->next;
00367          con->schedcnt--;
00368 
00369          /*
00370           * At this point, the schedule queue is still intact.  We
00371           * have removed the first event and the rest is still there,
00372           * so it's permissible for the callback to add new events, but
00373           * trying to delete itself won't work because it isn't in
00374           * the schedule queue.  If that's what it wants to do, it 
00375           * should return 0.
00376           */
00377          
00378          ast_mutex_unlock(&con->lock);
00379          res = current->callback(current->data);
00380          ast_mutex_lock(&con->lock);
00381          
00382          if (res) {
00383             /*
00384              * If they return non-zero, we should schedule them to be
00385              * run again.
00386              */
00387             if (sched_settime(&current->when, current->resched)) {
00388                sched_release(con, current);
00389             } else
00390                schedule(con, current);
00391          } else {
00392             /* No longer needed, so release it */
00393             sched_release(con, current);
00394          }
00395          x++;
00396       } else
00397          break;
00398    }
00399    ast_mutex_unlock(&con->lock);
00400    return x;
00401 }

int ast_sched_wait struct sched_context con  ) 
 

Determines number of seconds until the next outstanding event to take place.

Parameters:
con context to act upon Determine the number of seconds until the next outstanding event should take place, and return the number of milliseconds until it needs to be run. This value is perfect for passing to the poll call. Returns "-1" if there is nothing there are no scheduled events (and thus the poll should not timeout)

Definition at line 141 of file sched.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, DEBUG, and LOG_DEBUG.

Referenced by ast_waitstream(), ast_waitstream_fr(), and ast_waitstream_full().

00142 {
00143    /*
00144     * Return the number of milliseconds 
00145     * until the next scheduled event
00146     */
00147    struct timeval tv;
00148    int ms;
00149    DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));
00150    ast_mutex_lock(&con->lock);
00151    if (!con->schedq) {
00152       ms = -1;
00153    } else if (gettimeofday(&tv, NULL) < 0) {
00154       /* This should never happen */
00155       ms = 0;
00156    } else {
00157       ms = (con->schedq->when.tv_sec - tv.tv_sec) * 1000;
00158       ms += (con->schedq->when.tv_usec - tv.tv_usec) / 1000;
00159       if (ms < 0)
00160          ms = 0;
00161    }
00162    ast_mutex_unlock(&con->lock);
00163    return ms;
00164    
00165 }

struct sched_context* sched_context_create void   ) 
 

New schedule context.

Definition at line 62 of file sched.c.

References sched_context::eventcnt, sched_context::lock, malloc, sched_context::schedcnt, and sched_context::schedq.

Referenced by ast_channel_alloc().

00063 {
00064    struct sched_context *tmp;
00065    tmp = malloc(sizeof(struct sched_context));
00066    if (tmp) {
00067             memset(tmp, 0, sizeof(struct sched_context));
00068       ast_mutex_init(&tmp->lock);
00069       tmp->eventcnt = 1;
00070       tmp->schedcnt = 0;
00071       tmp->schedq = NULL;
00072 #ifdef SCHED_MAX_CACHE
00073       tmp->schedc = NULL;
00074       tmp->schedccnt = 0;
00075 #endif
00076    }
00077    return tmp;
00078 }

void sched_context_destroy struct sched_context c  ) 
 

destroys a schedule context

Parameters:
c Context to free Destroys (free's) the given sched_context structure Returns 0 on success, -1 on failure

Definition at line 80 of file sched.c.

References ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, free, sched::next, and s.

Referenced by ast_hangup().

00081 {
00082    struct sched *s, *sl;
00083    ast_mutex_lock(&con->lock);
00084 #ifdef SCHED_MAX_CACHE
00085    /* Eliminate the cache */
00086    s = con->schedc;
00087    while(s) {
00088       sl = s;
00089       s = s->next;
00090       free(sl);
00091    }
00092 #endif
00093    /* And the queue */
00094    s = con->schedq;
00095    while(s) {
00096       sl = s;
00097       s = s->next;
00098       free(sl);
00099    }
00100    /* And the context */
00101    ast_mutex_unlock(&con->lock);
00102    ast_mutex_destroy(&con->lock);
00103    free(con);
00104 }


Generated on Wed Mar 16 20:08:38 2005 for Asterisk by  doxygen 1.4.0