summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2007-02-02 00:49:14 +0000
committerJoshua Colp <jcolp@digium.com>2007-02-02 00:49:14 +0000
commit8a889843ba4c043a52153f4222679ed8266c383d (patch)
tree4f53531bb9aea87279e4fc712fbc98f188bf8d96
parentae64c71d650409611954d93bc1743ba3540382be (diff)
Switch the devicestate thread to operate the same way as the logging thread. Pops all entries off the list to be processed, resets the list back to a clean state, and processes each entry. The thread won't have to acquire the list lock again until it checks to see if there are more to process.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@53112 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--main/devicestate.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/main/devicestate.c b/main/devicestate.c
index 78e8a19c3..74227a064 100644
--- a/main/devicestate.c
+++ b/main/devicestate.c
@@ -400,9 +400,7 @@ static int __ast_device_state_changed_literal(char *buf)
strcpy(change->device, device);
AST_LIST_LOCK(&state_changes);
AST_LIST_INSERT_TAIL(&state_changes, change, list);
- if (AST_LIST_FIRST(&state_changes) == change)
- /* the list was empty, signal the thread */
- ast_cond_signal(&change_pending);
+ ast_cond_signal(&change_pending);
AST_LIST_UNLOCK(&state_changes);
}
@@ -431,22 +429,22 @@ int ast_device_state_changed(const char *fmt, ...)
/*! \brief Go through the dev state change queue and update changes in the dev state thread */
static void *do_devstate_changes(void *data)
{
- struct state_change *cur;
+ struct state_change *next, *current;
- AST_LIST_LOCK(&state_changes);
for (;;) {
- /* the list lock will _always_ be held at this point in the loop */
- cur = AST_LIST_REMOVE_HEAD(&state_changes, list);
- if (cur) {
- /* we got an entry, so unlock the list while we process it */
- AST_LIST_UNLOCK(&state_changes);
- do_state_change(cur->device);
- free(cur);
- AST_LIST_LOCK(&state_changes);
- } else {
- /* there was no entry, so atomically unlock the list and wait for
- the condition to be signalled (returns with the lock held) */
+ /* This basically pops off any state change entries, resets the list back to NULL, unlocks, and processes each state change */
+ AST_LIST_LOCK(&state_changes);
+ if (AST_LIST_EMPTY(&state_changes))
ast_cond_wait(&change_pending, &state_changes.lock);
+ next = AST_LIST_FIRST(&state_changes);
+ AST_LIST_HEAD_INIT_NOLOCK(&state_changes);
+ AST_LIST_UNLOCK(&state_changes);
+
+ /* Process each state change */
+ while ((current = next)) {
+ next = AST_LIST_NEXT(current, list);
+ do_state_change(current->device);
+ free(current);
}
}