mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-28 07:01:07 +00:00
Fixes manager.c crash.
This issue was caused by improper use of the mansession lock and manession_session lock. These two structures are confusing to begin with so I'm not surprised this occurred. I fixed this by consistently making sure we use each of these locks only to protect the data in the corresponding structure. We had mismatched usage of these locks which resulted in no mutual exclusivity occurring at all. (closes issue #17994) Reported by: vrban Patches: mansession_locking_fix.diff uploaded by dvossel (license 671) Tested by: vrban git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@291227 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1978,11 +1978,11 @@ static int set_eventmask(struct mansession *s, const char *eventmask)
|
|||||||
{
|
{
|
||||||
int maskint = strings_to_mask(eventmask);
|
int maskint = strings_to_mask(eventmask);
|
||||||
|
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
if (maskint >= 0) {
|
if (maskint >= 0) {
|
||||||
s->session->send_events = maskint;
|
s->session->send_events = maskint;
|
||||||
}
|
}
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
|
|
||||||
return maskint;
|
return maskint;
|
||||||
}
|
}
|
||||||
@@ -2771,7 +2771,7 @@ static int action_waitevent(struct mansession *s, const struct message *m)
|
|||||||
/* XXX maybe put an upper bound, or prevent the use of 0 ? */
|
/* XXX maybe put an upper bound, or prevent the use of 0 ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
if (s->session->waiting_thread != AST_PTHREADT_NULL) {
|
if (s->session->waiting_thread != AST_PTHREADT_NULL) {
|
||||||
pthread_kill(s->session->waiting_thread, SIGURG);
|
pthread_kill(s->session->waiting_thread, SIGURG);
|
||||||
}
|
}
|
||||||
@@ -2795,14 +2795,14 @@ static int action_waitevent(struct mansession *s, const struct message *m)
|
|||||||
s->session->send_events = -1;
|
s->session->send_events = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
|
|
||||||
/* XXX should this go inside the lock ? */
|
/* XXX should this go inside the lock ? */
|
||||||
s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
|
s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
|
||||||
ast_debug(1, "Starting waiting for an event!\n");
|
ast_debug(1, "Starting waiting for an event!\n");
|
||||||
|
|
||||||
for (x = 0; x < timeout || timeout < 0; x++) {
|
for (x = 0; x < timeout || timeout < 0; x++) {
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
|
if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
|
||||||
needexit = 1;
|
needexit = 1;
|
||||||
}
|
}
|
||||||
@@ -2816,7 +2816,7 @@ static int action_waitevent(struct mansession *s, const struct message *m)
|
|||||||
if (s->session->needdestroy) {
|
if (s->session->needdestroy) {
|
||||||
needexit = 1;
|
needexit = 1;
|
||||||
}
|
}
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
if (needexit) {
|
if (needexit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2830,7 +2830,7 @@ static int action_waitevent(struct mansession *s, const struct message *m)
|
|||||||
}
|
}
|
||||||
ast_debug(1, "Finished waiting for an event!\n");
|
ast_debug(1, "Finished waiting for an event!\n");
|
||||||
|
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
if (s->session->waiting_thread == pthread_self()) {
|
if (s->session->waiting_thread == pthread_self()) {
|
||||||
struct eventqent *eqe = s->session->last_ev;
|
struct eventqent *eqe = s->session->last_ev;
|
||||||
astman_send_response(s, m, "Success", "Waiting for Event completed.");
|
astman_send_response(s, m, "Success", "Waiting for Event completed.");
|
||||||
@@ -2851,7 +2851,8 @@ static int action_waitevent(struct mansession *s, const struct message *m)
|
|||||||
} else {
|
} else {
|
||||||
ast_debug(1, "Abandoning event request!\n");
|
ast_debug(1, "Abandoning event request!\n");
|
||||||
}
|
}
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4544,21 +4545,20 @@ static int get_input(struct mansession *s, char *output)
|
|||||||
}
|
}
|
||||||
res = 0;
|
res = 0;
|
||||||
while (res == 0) {
|
while (res == 0) {
|
||||||
/* XXX do we really need this locking ? */
|
ao2_lock(s->session);
|
||||||
mansession_lock(s);
|
|
||||||
if (s->session->pending_event) {
|
if (s->session->pending_event) {
|
||||||
s->session->pending_event = 0;
|
s->session->pending_event = 0;
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s->session->waiting_thread = pthread_self();
|
s->session->waiting_thread = pthread_self();
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
|
|
||||||
res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */
|
res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */
|
||||||
|
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
s->session->waiting_thread = AST_PTHREADT_NULL;
|
s->session->waiting_thread = AST_PTHREADT_NULL;
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/* If we get a signal from some other thread (typically because
|
/* If we get a signal from some other thread (typically because
|
||||||
@@ -4571,7 +4571,7 @@ static int get_input(struct mansession *s, char *output)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mansession_lock(s);
|
ao2_lock(s->session);
|
||||||
res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
|
res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
|
||||||
if (res < 1) {
|
if (res < 1) {
|
||||||
res = -1; /* error return */
|
res = -1; /* error return */
|
||||||
@@ -4580,7 +4580,7 @@ static int get_input(struct mansession *s, char *output)
|
|||||||
src[s->session->inlen] = '\0';
|
src[s->session->inlen] = '\0';
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
mansession_unlock(s);
|
ao2_unlock(s->session);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user