[asterisk-commits] kmoore: branch kmoore/scheduler r410980 - in /team/kmoore/scheduler: include/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Mar 21 08:33:21 CDT 2014
Author: kmoore
Date: Fri Mar 21 08:33:05 2014
New Revision: 410980
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410980
Log:
Make ast_sched_del non-blocking
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=410980&r1=410979&r2=410980
==============================================================================
--- team/kmoore/scheduler/include/asterisk/sched.h (original)
+++ team/kmoore/scheduler/include/asterisk/sched.h Fri Mar 21 08:33:05 2014
@@ -125,10 +125,9 @@
* \brief Deletes a scheduled event
*
* 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.
+ * event, but return 0 instead. If a scheduled event is deleted while executing,
+ * that event will be prevented from rescheduling itself. Additional deletion
+ * attempts will result in failure, even if the callback is still executing.
*
* \param con scheduling context to delete item from
* \param id ID of the scheduled item to delete
Modified: team/kmoore/scheduler/main/sched.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/scheduler/main/sched.c?view=diff&rev=410980&r1=410979&r2=410980
==============================================================================
--- team/kmoore/scheduler/main/sched.c (original)
+++ team/kmoore/scheduler/main/sched.c Fri Mar 21 08:33:05 2014
@@ -67,9 +67,10 @@
int id; /*!< ID number of event */
struct timeval when; /*!< Absolute time event should take place */
int resched; /*!< When to reschedule */
- int variable; /*!< Use return value from callback to reschedule */
void *object; /*!< AO2 object for callback */
ast_sched_cb callback; /*!< Callback */
+ unsigned int variable:1; /*!< Use return value from callback to reschedule */
+ unsigned int deleted:1; /*!< Flagged for deletion during execution */
ssize_t __heap_index;
};
@@ -82,9 +83,10 @@
struct ast_sched_context {
ast_mutex_t lock;
unsigned int eventcnt; /*!< Number of events processed */
- unsigned int highwater; /*!< highest count so far */
+ unsigned int highwater; /*!< highest count so far */
struct ast_heap *sched_heap;
struct sched_thread *sched_thread;
+ struct sched *current; /*!< Scheduler entry currently being processed */
#ifdef SCHED_MAX_CACHE
AST_LIST_HEAD_NOLOCK(, sched) schedc; /*!< Cache of unused schedule structures and how many */
@@ -455,6 +457,9 @@
}
sched_release(con, s);
+ } else if (con->current && con->current->id == id && !con->current->deleted) {
+ con->current->deleted = 1;
+ s = con->current;
}
#ifdef DUMP_SCHEDULER
@@ -562,7 +567,6 @@
*/
int ast_sched_runq(struct ast_sched_context *con)
{
- struct sched *current;
struct timeval when;
int numevents;
int res;
@@ -572,17 +576,17 @@
ast_mutex_lock(&con->lock);
when = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));
- for (numevents = 0; (current = ast_heap_peek(con->sched_heap, 1)); numevents++) {
+ for (numevents = 0; (con->current = ast_heap_peek(con->sched_heap, 1)); numevents++) {
/* schedule all events which are going to expire within 1ms.
* We only care about millisecond accuracy anyway, so this will
* help us get more than one event at one time if they are very
* close together.
*/
- if (ast_tvcmp(current->when, when) != -1) {
+ if (ast_tvcmp(con->current->when, when) != -1) {
break;
}
- current = ast_heap_pop(con->sched_heap);
+ con->current = ast_heap_pop(con->sched_heap);
/*
* At this point, the schedule queue is still intact. We
@@ -593,23 +597,27 @@
* should return 0.
*/
+ ast_mutex_unlock(&con->lock);
res = current->callback(current->object);
- if (res) {
+ ast_mutex_lock(&con->lock);
+
+ if (res && !con->current->deleted) {
/*
* If they return non-zero, we should schedule them to be
* run again.
*/
- if (sched_settime(¤t->when, current->variable? res : current->resched)) {
- sched_release(con, current);
+ if (sched_settime(&con->current->when, con->current->variable ? res : con->current->resched)) {
+ sched_release(con, con->current);
} else {
- schedule(con, current);
+ schedule(con, con->current);
}
} else {
/* No longer needed, so release it */
- sched_release(con, current);
- }
- }
-
+ sched_release(con, con->current);
+ }
+ }
+
+ con->current = NULL;
ast_mutex_unlock(&con->lock);
return numevents;
More information about the asterisk-commits
mailing list