time_t noncetime; /*!< Timer for nonce value expiration */
unsigned long oldnonce; /*!< Stale nonce value */
unsigned long nc; /*!< incremental nonce counter */
+ ast_mutex_t notify_lock; /*!< Lock for notifying this session of events */
AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */
AST_LIST_ENTRY(mansession_session) list;
};
if (session->blackfilters) {
ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one");
}
+
+ ast_mutex_destroy(&session->notify_lock);
}
/*! \brief Allocate manager session structure and add it to the list of sessions */
newsession->send_events = -1;
ast_sockaddr_copy(&newsession->addr, addr);
+ ast_mutex_init(&newsession->notify_lock);
+
sessions = ao2_global_obj_ref(mgr_sessions);
if (sessions) {
ao2_link(sessions, newsession);
/* XXX maybe put an upper bound, or prevent the use of 0 ? */
}
- ao2_lock(s->session);
+ ast_mutex_lock(&s->session->notify_lock);
if (s->session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(s->session->waiting_thread, SIGURG);
}
+ ast_mutex_unlock(&s->session->notify_lock);
+
+ ao2_lock(s->session);
if (s->session->managerid) { /* AMI-over-HTTP session */
/*
}
ao2_unlock(s->session);
- /* XXX should this go inside the lock ? */
+ ast_mutex_lock(&s->session->notify_lock);
s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
+ ast_mutex_unlock(&s->session->notify_lock);
ast_debug(1, "Starting waiting for an event!\n");
for (x = 0; x < timeout || timeout < 0; x++) {
if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
needexit = 1;
}
+ if (s->session->needdestroy) {
+ needexit = 1;
+ }
+ ao2_unlock(s->session);
/* We can have multiple HTTP session point to the same mansession entry.
* The way we deal with it is not very nice: newcomers kick out the previous
* HTTP session. XXX this needs to be improved.
*/
+ ast_mutex_lock(&s->session->notify_lock);
if (s->session->waiting_thread != pthread_self()) {
needexit = 1;
}
- if (s->session->needdestroy) {
- needexit = 1;
- }
- ao2_unlock(s->session);
+ ast_mutex_unlock(&s->session->notify_lock);
if (needexit) {
break;
}
}
ast_debug(1, "Finished waiting for an event!\n");
- ao2_lock(s->session);
+ ast_mutex_lock(&s->session->notify_lock);
if (s->session->waiting_thread == pthread_self()) {
struct eventqent *eqe = s->session->last_ev;
+
+ s->session->waiting_thread = AST_PTHREADT_NULL;
+ ast_mutex_unlock(&s->session->notify_lock);
+
+ ao2_lock(s->session);
astman_send_response(s, m, "Success", "Waiting for Event completed.");
while ((eqe = advance_event(eqe))) {
if (((s->session->readperm & eqe->category) == eqe->category)
"Event: WaitEventComplete\r\n"
"%s"
"\r\n", idText);
- s->session->waiting_thread = AST_PTHREADT_NULL;
+ ao2_unlock(s->session);
} else {
+ ast_mutex_unlock(&s->session->notify_lock);
ast_debug(1, "Abandoning event request!\n");
}
- ao2_unlock(s->session);
return 0;
}
}
}
- ao2_lock(s->session);
+ ast_mutex_lock(&s->session->notify_lock);
if (s->session->pending_event) {
s->session->pending_event = 0;
- ao2_unlock(s->session);
+ ast_mutex_unlock(&s->session->notify_lock);
return 0;
}
s->session->waiting_thread = pthread_self();
- ao2_unlock(s->session);
+ ast_mutex_unlock(&s->session->notify_lock);
res = ast_wait_for_input(ast_iostream_get_fd(s->session->stream), timeout);
- ao2_lock(s->session);
+ ast_mutex_lock(&s->session->notify_lock);
s->session->waiting_thread = AST_PTHREADT_NULL;
- ao2_unlock(s->session);
+ ast_mutex_unlock(&s->session->notify_lock);
}
if (res < 0) {
/* If we get a signal from some other thread (typically because
iter = ao2_iterator_init(sessions, 0);
while ((session = ao2_iterator_next(&iter))) {
- ao2_lock(session);
+ ast_mutex_lock(&session->notify_lock);
if (session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(session->waiting_thread, SIGURG);
} else {
*/
session->pending_event = 1;
}
- ao2_unlock(session);
+ ast_mutex_unlock(&session->notify_lock);
unref_mansession(session);
}
ao2_iterator_destroy(&iter);
blastaway = 1;
} else {
ast_debug(1, "Need destroy, but can't do it yet!\n");
+ ast_mutex_lock(&session->notify_lock);
if (session->waiting_thread != AST_PTHREADT_NULL) {
pthread_kill(session->waiting_thread, SIGURG);
}
+ ast_mutex_unlock(&session->notify_lock);
session->inuse--;
}
} else {