Thu Jul 9 13:40:41 2009

Asterisk developer's documentation


sched.h

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  * \brief Scheduler Routines (derived from cheops)
00021  */
00022 
00023 #ifndef _ASTERISK_SCHED_H
00024 #define _ASTERISK_SCHED_H
00025 
00026 #if defined(__cplusplus) || defined(c_plusplus)
00027 extern "C" {
00028 #endif
00029 
00030 /*! \brief Max num of schedule structs
00031  * \note The max number of schedule structs to keep around
00032  * for use.  Undefine to disable schedule structure
00033  * caching. (Only disable this on very low memory
00034  * machines)
00035  */
00036 #define SCHED_MAX_CACHE 128
00037 
00038 /*! \brief a loop construct to ensure that
00039  * the scheduled task get deleted. The idea is that
00040  * if we loop attempting to remove the scheduled task,
00041  * then whatever callback had been running will complete
00042  * and reinsert the task into the scheduler.
00043  *
00044  * Since macro expansion essentially works like pass-by-name
00045  * parameter passing, this macro will still work correctly even
00046  * if the id of the task to delete changes. This holds as long as 
00047  * the name of the id which could change is passed to the macro 
00048  * and not a copy of the value of the id.
00049  */
00050 #define AST_SCHED_DEL(sched, id) \
00051    do { \
00052       int _count = 0; \
00053       while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
00054          usleep(1); \
00055       } \
00056       if (_count == 10) \
00057          ast_debug(3, "Unable to cancel schedule ID %d.\n", id); \
00058       id = -1; \
00059    } while (0);
00060 
00061 #define AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, variable) \
00062    do { \
00063       int _count = 0; \
00064       while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
00065          usleep(1); \
00066       } \
00067       if (_count == 10) \
00068          ast_log(LOG_WARNING, "Unable to cancel schedule ID %d.  This is probably a bug (%s: %s, line %d).\n", id, __FILE__, __PRETTY_FUNCTION__, __LINE__); \
00069       id = ast_sched_add_variable(sched, when, callback, data, variable); \
00070    } while (0);
00071 
00072 #define AST_SCHED_REPLACE(id, sched, when, callback, data) \
00073       AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, 0)
00074 
00075 struct sched_context;
00076 
00077 /*! \brief New schedule context
00078  * \note Create a scheduling context
00079  * \return Returns a malloc'd sched_context structure, NULL on failure
00080  */
00081 struct sched_context *sched_context_create(void);
00082 
00083 /*! \brief destroys a schedule context
00084  * Destroys (free's) the given sched_context structure
00085  * \param c Context to free
00086  * \return Returns 0 on success, -1 on failure
00087  */
00088 void sched_context_destroy(struct sched_context *c);
00089 
00090 /*! \brief callback for a cheops scheduler
00091  * A cheops scheduler callback takes a pointer with callback data and
00092  * \return returns a 0 if it should not be run again, or non-zero if it should be
00093  * rescheduled to run again
00094  */
00095 typedef int (*ast_sched_cb)(const void *data);
00096 #define AST_SCHED_CB(a) ((ast_sched_cb)(a))
00097 
00098 /*! \brief Adds a scheduled event
00099  * Schedule an event to take place at some point in the future.  callback
00100  * will be called with data as the argument, when milliseconds into the
00101  * future (approximately)
00102  * If callback returns 0, no further events will be re-scheduled
00103  * \param con Scheduler context to add
00104  * \param when how many milliseconds to wait for event to occur
00105  * \param callback function to call when the amount of time expires
00106  * \param data data to pass to the callback
00107  * \return Returns a schedule item ID on success, -1 on failure
00108  */
00109 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data);
00110 
00111 /*!
00112  * \brief replace a scheduler entry
00113  * \deprecated You should use the AST_SCHED_REPLACE() macro instead.
00114  *
00115  * This deletes the scheduler entry for old_id if it exists, and then
00116  * calls ast_sched_add to create a new entry.  A negative old_id will
00117  * be ignored.
00118  *
00119  * \retval -1 failure
00120  * \retval otherwise, returns scheduled item ID
00121  */
00122 int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data);
00123 
00124 /*!Adds a scheduled event with rescheduling support
00125  * \param con Scheduler context to add
00126  * \param when how many milliseconds to wait for event to occur
00127  * \param callback function to call when the amount of time expires
00128  * \param data data to pass to the callback
00129  * \param variable If true, the result value of callback function will be
00130  *       used for rescheduling
00131  * Schedule an event to take place at some point in the future.  Callback
00132  * will be called with data as the argument, when milliseconds into the
00133  * future (approximately)
00134  * If callback returns 0, no further events will be re-scheduled
00135  * \return Returns a schedule item ID on success, -1 on failure
00136  */
00137 int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable);
00138 
00139 /*!
00140  * \brief replace a scheduler entry
00141  * \deprecated You should use the AST_SCHED_REPLACE_VARIABLE() macro instead.
00142  *
00143  * This deletes the scheduler entry for old_id if it exists, and then
00144  * calls ast_sched_add to create a new entry.  A negative old_id will
00145  * be ignored.
00146  *
00147  * \retval -1 failure
00148  * \retval otherwise, returns scheduled item ID
00149  */
00150 int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable);
00151 
00152 /*! \brief Deletes a scheduled event
00153  * Remove this event from being run.  A procedure should not remove its own
00154  * event, but return 0 instead.  In most cases, you should not call this
00155  * routine directly, but use the AST_SCHED_DEL() macro instead (especially if
00156  * you don't intend to do something different when it returns failure).
00157  * \param con scheduling context to delete item from
00158  * \param id ID of the scheduled item to delete
00159  * \return Returns 0 on success, -1 on failure
00160  */
00161 #ifndef AST_DEVMODE
00162 int ast_sched_del(struct sched_context *con, int id);
00163 #else
00164 int _ast_sched_del(struct sched_context *con, int id, const char *file, int line, const char *function);
00165 #define  ast_sched_del(a, b)  _ast_sched_del(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00166 #endif
00167 
00168 /*! \brief Determines number of seconds until the next outstanding event to take place
00169  * Determine the number of seconds until the next outstanding event
00170  * should take place, and return the number of milliseconds until
00171  * it needs to be run.  This value is perfect for passing to the poll
00172  * call.
00173  * \param con context to act upon
00174  * \return Returns "-1" if there is nothing there are no scheduled events
00175  * (and thus the poll should not timeout)
00176  */
00177 int ast_sched_wait(struct sched_context *con);
00178 
00179 /*! \brief Runs the queue
00180  * \param con Scheduling context to run
00181  * Run the queue, executing all callbacks which need to be performed
00182  * at this time.
00183  * \param con context to act upon
00184  * \return Returns the number of events processed.
00185  */
00186 int ast_sched_runq(struct sched_context *con);
00187 
00188 /*! \brief Dumps the scheduler contents
00189  * Debugging: Dump the contents of the scheduler to stderr
00190  * \param con Context to dump
00191  */
00192 void ast_sched_dump(const struct sched_context *con);
00193 
00194 /*! \brief Returns the number of seconds before an event takes place
00195  * \param con Context to use
00196  * \param id Id to dump
00197  */
00198 long ast_sched_when(struct sched_context *con,int id);
00199 
00200 /*!
00201  * \brief Convenience macro for objects and reference (add)
00202  *
00203  */
00204 #define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj)))
00205 
00206 /*!
00207  * \brief Convenience macro for objects and reference (del)
00208  *
00209  */
00210 #define ast_sched_del_object(obj,destructor,con,id) do { \
00211    if ((id) > -1) { \
00212       ast_sched_del((con),(id)); \
00213       (id) = -1; \
00214       ASTOBJ_UNREF((obj),(destructor)); \
00215    } \
00216 } while(0)
00217 
00218 #if defined(__cplusplus) || defined(c_plusplus)
00219 }
00220 #endif
00221 
00222 #endif /* _ASTERISK_SCHED_H */

Generated on Thu Jul 9 13:40:41 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7