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 ({ \ 00052 int _count = 0; \ 00053 int _sched_res = -1; \ 00054 while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \ 00055 usleep(1); \ 00056 if (_count == 10 && option_debug > 2) { \ 00057 ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \ 00058 } \ 00059 id = -1; \ 00060 (_sched_res); \ 00061 }) 00062 00063 struct sched_context; 00064 00065 /*! \brief New schedule context 00066 * \note Create a scheduling context 00067 * \return Returns a malloc'd sched_context structure, NULL on failure 00068 */ 00069 struct sched_context *sched_context_create(void); 00070 00071 /*! \brief destroys a schedule context 00072 * Destroys (free's) the given sched_context structure 00073 * \param c Context to free 00074 * \return Returns 0 on success, -1 on failure 00075 */ 00076 void sched_context_destroy(struct sched_context *c); 00077 00078 /*! \brief callback for a cheops scheduler 00079 * A cheops scheduler callback takes a pointer with callback data and 00080 * \return returns a 0 if it should not be run again, or non-zero if it should be 00081 * rescheduled to run again 00082 */ 00083 typedef int (*ast_sched_cb)(const void *data); 00084 #define AST_SCHED_CB(a) ((ast_sched_cb)(a)) 00085 00086 /*! \brief Adds a scheduled event 00087 * Schedule an event to take place at some point in the future. callback 00088 * will be called with data as the argument, when milliseconds into the 00089 * future (approximately) 00090 * If callback returns 0, no further events will be re-scheduled 00091 * \param con Scheduler context to add 00092 * \param when how many milliseconds to wait for event to occur 00093 * \param callback function to call when the amount of time expires 00094 * \param data data to pass to the callback 00095 * \return Returns a schedule item ID on success, -1 on failure 00096 */ 00097 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data); 00098 00099 /*!Adds a scheduled event with rescheduling support 00100 * \param con Scheduler context to add 00101 * \param when how many milliseconds to wait for event to occur 00102 * \param callback function to call when the amount of time expires 00103 * \param data data to pass to the callback 00104 * \param variable If true, the result value of callback function will be 00105 * used for rescheduling 00106 * Schedule an event to take place at some point in the future. Callback 00107 * will be called with data as the argument, when milliseconds into the 00108 * future (approximately) 00109 * If callback returns 0, no further events will be re-scheduled 00110 * \return Returns a schedule item ID on success, -1 on failure 00111 */ 00112 int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable); 00113 00114 /*! \brief Deletes a scheduled event 00115 * Remove this event from being run. A procedure should not remove its 00116 * own event, but return 0 instead. 00117 * \param con scheduling context to delete item from 00118 * \param id ID of the scheduled item to delete 00119 * \return Returns 0 on success, -1 on failure 00120 */ 00121 int ast_sched_del(struct sched_context *con, int id); 00122 00123 /*! \brief Determines number of seconds until the next outstanding event to take place 00124 * Determine the number of seconds until the next outstanding event 00125 * should take place, and return the number of milliseconds until 00126 * it needs to be run. This value is perfect for passing to the poll 00127 * call. 00128 * \param con context to act upon 00129 * \return Returns "-1" if there is nothing there are no scheduled events 00130 * (and thus the poll should not timeout) 00131 */ 00132 int ast_sched_wait(struct sched_context *con); 00133 00134 /*! \brief Runs the queue 00135 * \param con Scheduling context to run 00136 * Run the queue, executing all callbacks which need to be performed 00137 * at this time. 00138 * \param con context to act upon 00139 * \return Returns the number of events processed. 00140 */ 00141 int ast_sched_runq(struct sched_context *con); 00142 00143 /*! \brief Dumps the scheduler contents 00144 * Debugging: Dump the contents of the scheduler to stderr 00145 * \param con Context to dump 00146 */ 00147 void ast_sched_dump(const struct sched_context *con); 00148 00149 /*! \brief Returns the number of seconds before an event takes place 00150 * \param con Context to use 00151 * \param id Id to dump 00152 */ 00153 long ast_sched_when(struct sched_context *con,int id); 00154 00155 /*! 00156 * \brief Convenience macro for objects and reference (add) 00157 * 00158 */ 00159 #define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj))) 00160 00161 /*! 00162 * \brief Convenience macro for objects and reference (del) 00163 * 00164 */ 00165 #define ast_sched_del_object(obj,destructor,con,id) do { \ 00166 if ((id) > -1) { \ 00167 ast_sched_del((con),(id)); \ 00168 (id) = -1; \ 00169 ASTOBJ_UNREF((obj),(destructor)); \ 00170 } \ 00171 } while(0) 00172 00173 #if defined(__cplusplus) || defined(c_plusplus) 00174 } 00175 #endif 00176 00177 #endif /* _ASTERISK_SCHED_H */