summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2008-04-02 17:36:49 +0000
committerMark Michelson <mmichelson@digium.com>2008-04-02 17:36:49 +0000
commit2580dfc6fbc0f432a55ec554b373ced9b71d9430 (patch)
tree004473913dbdcbdaddba45f26fa4a7cfc2bd03bd /main
parentb5cccfe1a408c2e5ba59404657afebfe0469f00c (diff)
Merged revisions 112468 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r112468 | mmichelson | 2008-04-02 12:36:04 -0500 (Wed, 02 Apr 2008) | 13 lines Fix a race condition in the manager. It is possible that a new manager event could be appended during a brief time when the manager is not waiting for input. If an event comes during this period, we need to set an indicator that there is an event pending so that the manager doesn't attempt to wait forever for an event that already happened. (closes issue #12354) Reported by: bamby Patches: manager_race_condition.diff uploaded by bamby (license 430) (comments added by me) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@112469 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/manager.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/main/manager.c b/main/manager.c
index ed9ea9ec3..a9147c570 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -168,6 +168,7 @@ struct mansession {
int send_events; /*!< XXX what ? */
struct eventqent *last_ev; /*!< last event processed. */
int writetimeout; /*!< Timeout for ast_carefulwrite() */
+ int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */
AST_LIST_ENTRY(mansession) list;
};
@@ -2822,6 +2823,11 @@ static int get_input(struct mansession *s, char *output)
while (res == 0) {
/* XXX do we really need this locking ? */
ast_mutex_lock(&s->__lock);
+ if (s->pending_event) {
+ s->pending_event = 0;
+ ast_mutex_unlock(&s->__lock);
+ return 0;
+ }
s->waiting_thread = pthread_self();
ast_mutex_unlock(&s->__lock);
@@ -3062,6 +3068,13 @@ int __manager_event(int category, const char *event,
ast_mutex_lock(&s->__lock);
if (s->waiting_thread != AST_PTHREADT_NULL)
pthread_kill(s->waiting_thread, SIGURG);
+ else
+ /* We have an event to process, but the mansession is
+ * not waiting for it. We still need to indicate that there
+ * is an event waiting so that get_input processes the pending
+ * event instead of polling.
+ */
+ s->pending_event = 1;
ast_mutex_unlock(&s->__lock);
}
AST_LIST_UNLOCK(&sessions);