[asterisk-commits] kmoore: branch kmoore/scheduler r410932 - in /team/kmoore/scheduler: include/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 19 10:27:27 CDT 2014
Author: kmoore
Date: Wed Mar 19 10:27:21 2014
New Revision: 410932
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410932
Log:
Modify the scheduler API to be more sane
Modified:
team/kmoore/scheduler/include/asterisk/sched.h
team/kmoore/scheduler/main/sched.c
Modified: team/kmoore/scheduler/include/asterisk/sched.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/scheduler/include/asterisk/sched.h?view=diff&rev=410932&r1=410931&r2=410932
==============================================================================
--- team/kmoore/scheduler/include/asterisk/sched.h (original)
+++ team/kmoore/scheduler/include/asterisk/sched.h Wed Mar 19 10:27:21 2014
@@ -28,123 +28,6 @@
extern "C" {
#endif
-/*!
- * \brief Remove a scheduler entry
- *
- * This is a loop construct to ensure that
- * the scheduled task get deleted. The idea is that
- * if we loop attempting to remove the scheduled task,
- * then whatever callback had been running will complete
- * and reinsert the task into the scheduler.
- *
- * Since macro expansion essentially works like pass-by-name
- * parameter passing, this macro will still work correctly even
- * if the id of the task to delete changes. This holds as long as
- * the name of the id which could change is passed to the macro
- * and not a copy of the value of the id.
- */
-#define AST_SCHED_DEL(sched, id) \
- ({ \
- int _count = 0; \
- int _sched_res = -1; \
- while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \
- usleep(1); \
- if (_count == 10) { \
- ast_debug(3, "Unable to cancel schedule ID %d.\n", id); \
- } \
- id = -1; \
- (_sched_res); \
- })
-
-#define AST_SCHED_DEL_ACCESSOR(sched, obj, getter, setter) \
- ({ \
- int _count = 0; \
- int _sched_res = -1; \
- while (getter(obj) > -1 && (_sched_res = ast_sched_del(sched, getter(obj))) && ++_count < 10) \
- usleep(1); \
- if (_count == 10) { \
- ast_debug(3, "Unable to cancel schedule ID %d.\n", getter(obj)); \
- } \
- setter(obj, -1); \
- (_sched_res); \
- })
-
-/*!
- * \brief schedule task to get deleted and call unref function
- * \sa AST_SCHED_DEL
- * \since 1.6.1
- */
-#define AST_SCHED_DEL_UNREF(sched, id, refcall) \
- do { \
- int _count = 0; \
- while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
- usleep(1); \
- } \
- if (_count == 10) \
- 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__); \
- if (id > -1) \
- refcall; \
- id = -1; \
- } while (0);
-
-/*!
- * \brief schedule task to get deleted releasing the lock between attempts
- * \since 1.6.1
- */
-#define AST_SCHED_DEL_SPINLOCK(sched, id, lock) \
- ({ \
- int _count = 0; \
- int _sched_res = -1; \
- while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) { \
- ast_mutex_unlock(lock); \
- usleep(1); \
- ast_mutex_lock(lock); \
- } \
- if (_count == 10) { \
- ast_debug(3, "Unable to cancel schedule ID %d.\n", id); \
- } \
- id = -1; \
- (_sched_res); \
- })
-
-#define AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, variable) \
- do { \
- int _count = 0; \
- while (id > -1 && ast_sched_del(sched, id) && ++_count < 10) { \
- usleep(1); \
- } \
- if (_count == 10) \
- 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__); \
- id = ast_sched_add_variable(sched, when, callback, data, variable); \
- } while (0);
-
-#define AST_SCHED_REPLACE(id, sched, when, callback, data) \
- AST_SCHED_REPLACE_VARIABLE(id, sched, when, callback, data, 0)
-
-/*!
- * \note Not currently used in the source?
- * \since 1.6.1
- */
-#define AST_SCHED_REPLACE_VARIABLE_UNREF(id, sched, when, callback, data, variable, unrefcall, addfailcall, refcall) \
- do { \
- int _count = 0, _res=1; \
- void *_data = (void *)ast_sched_find_data(sched, id); \
- while (id > -1 && (_res = ast_sched_del(sched, id) && _count++ < 10)) { \
- usleep(1); \
- } \
- if (!_res && _data) \
- unrefcall; /* should ref _data! */ \
- if (_count == 10) \
- 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__); \
- refcall; \
- id = ast_sched_add_variable(sched, when, callback, data, variable); \
- if (id == -1) \
- addfailcall; \
- } while (0);
-
-#define AST_SCHED_REPLACE_UNREF(id, sched, when, callback, data, unrefcall, addfailcall, refcall) \
- AST_SCHED_REPLACE_VARIABLE_UNREF(id, sched, when, callback, data, 0, unrefcall, addfailcall, refcall)
-
/*!
* \brief Create a scheduler context
*
@@ -164,10 +47,12 @@
*
* A scheduler callback takes a pointer with callback data and
*
+ * \param obj The data provided when the event was scheduled
+ *
* \retval 0 if the callback should not be rescheduled
- * \retval non-zero if the callback should be scheduled agai
- */
-typedef int (*ast_sched_cb)(const void *data);
+ * \retval non-zero if the callback should be scheduled again
+ */
+typedef int (*ast_sched_cb)(void *obj);
#define AST_SCHED_CB(a) ((ast_sched_cb)(a))
struct ast_cb_names {
@@ -178,6 +63,7 @@
/*!
* \brief Show statics on what it is in the schedule queue
+ *
* \param con Schedule context to check
* \param buf dynamic string to store report
* \param cbnames to check against
@@ -197,24 +83,11 @@
* \param con Scheduler context to add
* \param when how many milliseconds to wait for event to occur
* \param callback function to call when the amount of time expires
- * \param data data to pass to the callback
+ * \param obj AO2 object to pass to the callback
*
* \return Returns a schedule item ID on success, -1 on failure
*/
-int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result;
-
-/*!
- * \brief replace a scheduler entry
- * \deprecated You should use the AST_SCHED_REPLACE() macro instead.
- *
- * This deletes the scheduler entry for old_id if it exists, and then
- * calls ast_sched_add to create a new entry. A negative old_id will
- * be ignored.
- *
- * \retval -1 failure
- * \retval otherwise, returns scheduled item ID
- */
-int ast_sched_replace(int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result;
+#define ast_sched_add(con, when, callback, obj) ast_sched_add_variable(con, when, callback, obj, 0)
/*!
* \brief Adds a scheduled event with rescheduling support
@@ -222,7 +95,7 @@
* \param con Scheduler context to add
* \param when how many milliseconds to wait for event to occur
* \param callback function to call when the amount of time expires
- * \param data data to pass to the callback
+ * \param obj AO2 object to pass to the callback
* \param variable If true, the result value of callback function will be
* used for rescheduling
*
@@ -234,39 +107,28 @@
*
* \return Returns a schedule item ID on success, -1 on failure
*/
-int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result;
-
-/*!
- * \brief replace a scheduler entry
- * \deprecated You should use the AST_SCHED_REPLACE_VARIABLE() macro instead.
- *
- * This deletes the scheduler entry for old_id if it exists, and then
- * calls ast_sched_add to create a new entry. A negative old_id will
- * be ignored.
- *
- * \retval -1 failure
- * \retval otherwise, returns scheduled item ID
- */
-int ast_sched_replace_variable(int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result;
+int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, void *obj, int variable) attribute_warn_unused_result;
/*!
* \brief Find a sched structure and return the data field associated with it.
+ * \since 1.6.1
*
* \param con scheduling context in which to search fro the matching id
* \param id ID of the scheduled item to find
- * \return the data field from the matching sched struct if found; else return NULL if not found.
- *
- * \since 1.6.1
- */
-const void *ast_sched_find_data(struct ast_sched_context *con, int id);
+ *
+ * \return the AO2 object from the matching scheduled event (must be ao2_cleanup()d)
+ * \return NULL if not found or object not provided
+ */
+void *ast_sched_find_data(struct ast_sched_context *con, int id);
/*!
* \brief Deletes a scheduled event
*
- * Remove this event from being run. A procedure should not remove its own
- * event, but return 0 instead. In most cases, you should not call this
- * routine directly, but use the AST_SCHED_DEL() macro instead (especially if
- * you don't intend to do something different when it returns failure).
+ * Remove this event from being run. A procedure should not remove its own
+ * event, but return 0 instead.
+ *
+ * The caller must not hold locks that the callback acquires when attempting
+ * to delete the scheduled event. This call is blocking on callback execution.
*
* \param con scheduling context to delete item from
* \param id ID of the scheduled item to delete
@@ -326,24 +188,6 @@
long ast_sched_when(struct ast_sched_context *con,int id);
/*!
- * \brief Convenience macro for objects and reference (add)
- *
- */
-#define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj)))
-
-/*!
- * \brief Convenience macro for objects and reference (del)
- *
- */
-#define ast_sched_del_object(obj,destructor,con,id) do { \
- if ((id) > -1) { \
- ast_sched_del((con),(id)); \
- (id) = -1; \
- ASTOBJ_UNREF((obj),(destructor)); \
- } \
-} while(0)
-
-/*!
* \brief Start a thread for processing scheduler entries
*
* \param con the scheduler context this thread will manage
Modified: team/kmoore/scheduler/main/sched.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/scheduler/main/sched.c?view=diff&rev=410932&r1=410931&r2=410932
==============================================================================
--- team/kmoore/scheduler/main/sched.c (original)
+++ team/kmoore/scheduler/main/sched.c Wed Mar 19 10:27:21 2014
@@ -68,7 +68,7 @@
struct timeval when; /*!< Absolute time event should take place */
int resched; /*!< When to reschedule */
int variable; /*!< Use return value from callback to reschedule */
- const void *data; /*!< Data */
+ void *object; /*!< AO2 object for callback */
ast_sched_cb callback; /*!< Callback */
ssize_t __heap_index;
};
@@ -261,6 +261,8 @@
* Add to the cache, or just free() if we
* already have too many cache entries
*/
+ ao2_cleanup(tmp->obj);
+ tmp->obj = NULL;
#ifdef SCHED_MAX_CACHE
if (con->schedccnt < SCHED_MAX_CACHE) {
@@ -341,7 +343,7 @@
/*! \brief
* Schedule callback(data) to happen when ms into the future
*/
-int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
+int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, void *obj, int variable)
{
struct sched *tmp;
int res = -1;
@@ -352,7 +354,7 @@
if ((tmp = sched_alloc(con))) {
tmp->id = con->eventcnt++;
tmp->callback = callback;
- tmp->data = data;
+ tmp->object = ao2_bump(obj);
tmp->resched = when;
tmp->variable = variable;
tmp->when = ast_tv(0, 0);
@@ -415,7 +417,7 @@
s = sched_find(con, id);
if (s) {
- data = s->data;
+ data = ao2_bump(s->object);
}
ast_mutex_unlock(&con->lock);
@@ -547,7 +549,7 @@
ast_debug(1, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n",
q->id,
q->callback,
- q->data,
+ q->object,
(long)delta.tv_sec,
(long int)delta.tv_usec);
}
@@ -591,10 +593,7 @@
* should return 0.
*/
- ast_mutex_unlock(&con->lock);
- res = current->callback(current->data);
- ast_mutex_lock(&con->lock);
-
+ res = current->callback(current->object);
if (res) {
/*
* If they return non-zero, we should schedule them to be
More information about the asterisk-commits
mailing list