diff options
author | Joshua Colp <jcolp@digium.com> | 2007-02-02 00:49:14 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2007-02-02 00:49:14 +0000 |
commit | 8a889843ba4c043a52153f4222679ed8266c383d (patch) | |
tree | 4f53531bb9aea87279e4fc712fbc98f188bf8d96 /main | |
parent | ae64c71d650409611954d93bc1743ba3540382be (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
Diffstat (limited to 'main')
-rw-r--r-- | main/devicestate.c | 30 |
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); } } |