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