Merge "pjsip: restrict function PJSIP_PARSE_URI to parse only SIP/SIPS URIs"
authorGeorge Joseph <gjoseph@digium.com>
Thu, 28 Mar 2019 13:04:51 +0000 (08:04 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Thu, 28 Mar 2019 13:04:51 +0000 (08:04 -0500)
apps/app_queue.c
doc/CHANGES-staging/README.md [new file with mode: 0644]
doc/UPGRADE-staging/README.md [new file with mode: 0644]
main/manager.c

index 72bc57b..8982541 100644 (file)
        </function>
        <function name="QUEUE_MEMBER" language="en_US">
                <synopsis>
-                       Count number of members answering a queue.
+                       Provides a count of queue members based on the provided criteria, or updates a
+                       queue member's settings.
                </synopsis>
                <syntax>
                        <parameter name="queuename" required="false" />
diff --git a/doc/CHANGES-staging/README.md b/doc/CHANGES-staging/README.md
new file mode 100644 (file)
index 0000000..da0df2a
--- /dev/null
@@ -0,0 +1,33 @@
+## **DO NOT REMOVE THIS FILE!**
+
+The only files that should be added to this directory are ones that will be
+used by the release script to update the CHANGES file automatically. The only
+time that it is necessary to add something to the CHANGES-staging directory is
+if you are either adding a new feature to Asterisk or adding new functionality
+to an existing feature. The file does not need to have a meaningful name, but
+it probably should. If there are multiple items that need documenting, each can
+be separated with a subject line, which should always start with "Subject:",
+followed by the subject of the change. This is case sensitive! For example, if
+you are making a change to PJSIP, then you might add the file
+"res_pjsip_my_cool_feature" to this directory, with a short description of what
+it does. If you are adding multiple entries, they should be done in the same
+commit to avoid merge conflicts. Here's an example:
+
+> Subject: res_pjsip
+>
+> Here's a pretty good description of my new feature that explains exactly what
+> it does and how to use it.
+>
+> Subject: core
+> Master-Only: true
+>
+> Here's another description of something else I added that is a big enough
+> change to warrant another entry in the CHANGES file.
+
+Note that the second subject has another header: "Master-Only". Changes that go
+into the master branch and ONLY the master branch are the only ones that should
+have this header. Also, the value can only be "true" or "True". The
+"Master-Only" part of the header IS case-sensitive, however!
+
+For more information, check out the wiki page:
+https://wiki.asterisk.org/wiki/display/AST/CHANGES+and+UPGRADE.txt
diff --git a/doc/UPGRADE-staging/README.md b/doc/UPGRADE-staging/README.md
new file mode 100644 (file)
index 0000000..1ef9334
--- /dev/null
@@ -0,0 +1,32 @@
+## **DO NOT REMOVE THIS FILE!**
+
+The only files that should be added to this directory are ones that will be
+used by the release script to update the UPGRADE.txt file automatically. The
+only time that it is necessary to add something to the UPGRADE-staging directory
+is if you are making a breaking change to an existing feature in Asterisk. The
+file does not need to have a meaningful name, but it probably should. If there
+are multiple items that need documenting, each can be separated with a subject
+line, which should always start with "Subject:", followed by the subject of the
+change. This is case sensitive! For example, if you are making a change to PJSIP,
+then you might add the file "res_pjsip_breaking_change" to this directory, with
+a short description of what it does. If you are adding multiple entries, they
+should be done in the same commit to avoid merge conflicts. Here's an example:
+
+> Subject: res_pjsip
+>
+> Here's a pretty good description of what I changed that explains exactly what
+> it does and why it breaks things (and why they needed to be broken).
+>
+> Subject: core
+> Master-Only: true
+>
+> Here's another description of something else I added that is a big enough
+> change to warrant another entry in the UPDATE.txt file.
+
+Note that the second subject has another header: "Master-Only". Changes that go
+into the master branch and ONLY the master branch are the only ones that should
+have this header. Also, the value can only be "true" or "True". The
+"Master-Only" part of the header IS case-sensitive, however!
+
+For more information, check out the wiki page:
+https://wiki.asterisk.org/wiki/display/AST/CHANGES+and+UPGRADE.txt
index 8e7a8b2..cd2e79a 100644 (file)
@@ -1598,6 +1598,7 @@ struct mansession_session {
        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;
 };
@@ -2211,6 +2212,8 @@ static void session_destructor(void *obj)
        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 */
@@ -2236,6 +2239,8 @@ static struct mansession_session *build_mansession(const struct ast_sockaddr *ad
        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);
@@ -4162,10 +4167,13 @@ static int action_waitevent(struct mansession *s, const struct message *m)
                /* 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 */
                /*
@@ -4188,8 +4196,9 @@ static int action_waitevent(struct mansession *s, const struct message *m)
        }
        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++) {
@@ -4197,17 +4206,19 @@ static int action_waitevent(struct mansession *s, const struct message *m)
                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;
                }
@@ -4221,9 +4232,14 @@ static int action_waitevent(struct mansession *s, const struct message *m)
        }
        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)
@@ -4237,11 +4253,11 @@ static int action_waitevent(struct mansession *s, const struct message *m)
                        "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;
 }
@@ -6613,20 +6629,20 @@ static int get_input(struct mansession *s, char *output)
                        }
                }
 
-               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
@@ -7007,7 +7023,7 @@ static int __attribute__((format(printf, 9, 0))) __manager_event_sessions_va(
 
                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 {
@@ -7018,7 +7034,7 @@ static int __attribute__((format(printf, 9, 0))) __manager_event_sessions_va(
                                 */
                                session->pending_event = 1;
                        }
-                       ao2_unlock(session);
+                       ast_mutex_unlock(&session->notify_lock);
                        unref_mansession(session);
                }
                ao2_iterator_destroy(&iter);
@@ -7904,9 +7920,11 @@ static int generic_http_callback(struct ast_tcptls_session_instance *ser,
                        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 {