<p>George Joseph has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10135">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_voicemail: Remove need to subscribe to stasis<br><br>app_voicemail was using the stasis cache to build and maintain a<br>list of mailboxes that had subscribers.  It then used this list<br>to determine if a mailbox should be polled for new messages if<br>polling was enabled.  For this to work, stasis had to cache every<br>subscription and unsubscription to the mailbox which caused a lot of<br>overhead, both cpu and memory related.<br><br>Since polling is only required when changes are being made to<br>mailboxes outside of app_voicemail and since the number of mailboxes<br>that don't have any subscribers is likely to be very low, all<br>mailboxes are now polled instead of just the ones with subscribers.<br><br>This paves the way for disabling the caching of stasis subscription<br>change messages.<br><br>Change-Id: I5cceb737246949f9782955c64425b8bd25a9e9ee<br>---<br>M apps/app_voicemail.c<br>1 file changed, 107 insertions(+), 223 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/35/10135/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c</span><br><span>index c6e501c..9e3c532 100644</span><br><span>--- a/apps/app_voicemail.c</span><br><span>+++ b/apps/app_voicemail.c</span><br><span>@@ -1009,42 +1009,21 @@</span><br><span> static pthread_t poll_thread = AST_PTHREADT_NULL;</span><br><span> static unsigned char poll_thread_run;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! Subscription to MWI event subscription changes */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct stasis_subscription *mwi_sub_sub;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief An MWI subscription</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief A mailbox to be polled</span><br><span>  *</span><br><span style="color: hsl(0, 100%, 40%);">- * This is so we can keep track of which mailboxes are subscribed to.</span><br><span>  * This way, we know which mailboxes to poll when the pollmailboxes</span><br><span>  * option is being used.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-struct mwi_sub {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_ENTRY(mwi_sub) entry;</span><br><span style="color: hsl(120, 100%, 40%);">+struct poll_state {</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_ENTRY(poll_state) entry;</span><br><span>    int old_urgent;</span><br><span>      int old_new;</span><br><span>         int old_old;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *uniqueid;</span><br><span>      char mailbox[0];</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct mwi_sub_task {</span><br><span style="color: hsl(0, 100%, 40%);">- const char *mailbox;</span><br><span style="color: hsl(0, 100%, 40%);">-    const char *context;</span><br><span style="color: hsl(0, 100%, 40%);">-    const char *uniqueid;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_sub_task_dtor(struct mwi_sub_task *mwist)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_free((void *) mwist->mailbox);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_free((void *) mwist->context);</span><br><span style="color: hsl(0, 100%, 40%);">-   ast_free((void *) mwist->uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-  ast_free(mwist);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_taskprocessor *mwi_subscription_tps;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static AST_RWLIST_HEAD_STATIC(mwi_subs, mwi_sub);</span><br><span style="color: hsl(120, 100%, 40%);">+static AST_RWLIST_HEAD_STATIC(poll_list, poll_state);</span><br><span> </span><br><span> /* custom audio control prompts for voicemail playback */</span><br><span> static char listen_control_forward_key[12];</span><br><span>@@ -1122,7 +1101,7 @@</span><br><span> static int message_range_and_existence_check(struct vm_state *vms, const char *msg_ids [], size_t num_msgs, int *msg_nums, struct ast_vm_user *vmu);</span><br><span> static void notify_new_state(struct ast_vm_user *vmu);</span><br><span> static int append_vmu_info_astman(struct mansession *s, struct ast_vm_user *vmu, const char* event_name, const char* actionid);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+static void poll_mailbox(struct poll_state *poll_state);</span><br><span> </span><br><span> /*!</span><br><span>  * Place a message in the indicated folder</span><br><span>@@ -12310,6 +12289,43 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* A write lock on the poll list should already be held */</span><br><span style="color: hsl(120, 100%, 40%);">+static int append_poll_list(struct ast_vm_user *vmu)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t len;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct poll_state *poll_state;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      len = sizeof(*poll_state) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!ast_strlen_zero(vmu->mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              len += strlen(vmu->mailbox);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ast_strlen_zero(vmu->context)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              len += strlen(vmu->context) + 1; /* Allow for seperator */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   poll_state = ast_calloc(1, len);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!poll_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ast_strlen_zero(vmu->mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              strcpy(poll_state->mailbox, vmu->mailbox);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ast_strlen_zero(vmu->context)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              strcat(poll_state->mailbox, "@");</span><br><span style="color: hsl(120, 100%, 40%);">+                strcat(poll_state->mailbox, vmu->context);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_RWLIST_INSERT_TAIL(&poll_list, poll_state, entry);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  poll_mailbox(poll_state);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct ast_vm_user *find_or_create(const char *context, const char *box)</span><br><span> {</span><br><span>       struct ast_vm_user *vmu;</span><br><span>@@ -12346,6 +12362,7 @@</span><br><span>   ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox));</span><br><span> </span><br><span>  AST_LIST_INSERT_TAIL(&users, vmu, list);</span><br><span style="color: hsl(120, 100%, 40%);">+  append_poll_list(vmu);</span><br><span> </span><br><span>   return vmu;</span><br><span> }</span><br><span>@@ -13010,38 +13027,44 @@</span><br><span>         AST_CLI_DEFINE(handle_voicemail_reload, "Reload voicemail configuration"),</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void poll_subscribed_mailbox(struct mwi_sub *mwi_sub)</span><br><span style="color: hsl(120, 100%, 40%);">+static void poll_mailbox(struct poll_state *poll_state)</span><br><span> {</span><br><span>     int new = 0, old = 0, urgent = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   inboxcount2(mwi_sub->mailbox, &urgent, &new, &old);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  inboxcount2(poll_state->mailbox, &urgent, &new, &old);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(4, "Polled mailbox '%s' urgent: %d  new: %d  old: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          poll_state->mailbox, urgent, new, old);</span><br><span> </span><br><span> #ifdef IMAP_STORAGE</span><br><span>        if (imap_poll_logout) {</span><br><span style="color: hsl(0, 100%, 40%);">-         imap_logout(mwi_sub->mailbox);</span><br><span style="color: hsl(120, 100%, 40%);">+             imap_logout(poll_state->mailbox);</span><br><span>         }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) {</span><br><span style="color: hsl(0, 100%, 40%);">-             mwi_sub->old_urgent = urgent;</span><br><span style="color: hsl(0, 100%, 40%);">-                mwi_sub->old_new = new;</span><br><span style="color: hsl(0, 100%, 40%);">-              mwi_sub->old_old = old;</span><br><span style="color: hsl(0, 100%, 40%);">-              queue_mwi_event(NULL, mwi_sub->mailbox, urgent, new, old);</span><br><span style="color: hsl(0, 100%, 40%);">-           run_externnotify(NULL, mwi_sub->mailbox, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (urgent != poll_state->old_urgent || new != poll_state->old_new || old != poll_state->old_old) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_debug(4, "Notifying subscribers of mailbox '%s' urgent: %d  new: %d  old: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        poll_state->mailbox, urgent, new, old);</span><br><span style="color: hsl(120, 100%, 40%);">+            poll_state->old_urgent = urgent;</span><br><span style="color: hsl(120, 100%, 40%);">+           poll_state->old_new = new;</span><br><span style="color: hsl(120, 100%, 40%);">+         poll_state->old_old = old;</span><br><span style="color: hsl(120, 100%, 40%);">+         queue_mwi_event(NULL, poll_state->mailbox, urgent, new, old);</span><br><span style="color: hsl(120, 100%, 40%);">+              run_externnotify(NULL, poll_state->mailbox, NULL);</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void poll_subscribed_mailboxes(void)</span><br><span style="color: hsl(120, 100%, 40%);">+static void poll_all_mailboxes(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mwi_sub *mwi_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct poll_state *poll_state;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      AST_RWLIST_RDLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ast_strlen_zero(mwi_sub->mailbox)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    poll_subscribed_mailbox(mwi_sub);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_debug(3, "Polling mailboxes\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_RWLIST_RDLOCK(&poll_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_RWLIST_TRAVERSE(&poll_list, poll_state, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!ast_strlen_zero(poll_state->mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       poll_mailbox(poll_state);</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_UNLOCK(&mwi_subs);</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_UNLOCK(&poll_list);</span><br><span> }</span><br><span> </span><br><span> static void *mb_poll_thread(void *data)</span><br><span>@@ -13061,18 +13084,12 @@</span><br><span>           if (!poll_thread_run)</span><br><span>                        break;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-              poll_subscribed_mailboxes();</span><br><span style="color: hsl(120, 100%, 40%);">+          poll_all_mailboxes();</span><br><span>        }</span><br><span> </span><br><span>        return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_sub_destroy(struct mwi_sub *mwi_sub)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_free(mwi_sub->uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(mwi_sub);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #ifdef IMAP_STORAGE</span><br><span> static void imap_logout(const char *mailbox_id)</span><br><span> {</span><br><span>@@ -13110,153 +13127,21 @@</span><br><span> </span><br><span> static void imap_close_subscribed_mailboxes(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct mwi_sub *mwi_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct poll_state *poll_state;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      AST_RWLIST_RDLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ast_strlen_zero(mwi_sub->mailbox)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    imap_logout(mwi_sub->mailbox);</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_RDLOCK(&poll_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_RWLIST_TRAVERSE(&poll_list, poll_state, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!ast_strlen_zero(poll_state->mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       imap_logout(poll_state->mailbox);</span><br><span>                 }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_UNLOCK(&mwi_subs);</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_UNLOCK(&poll_list);</span><br><span> }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_unsubscribe(void *datap)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mwi_sub *mwi_sub;</span><br><span style="color: hsl(0, 100%, 40%);">-        char *uniqueid = datap;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_WRLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (!strcmp(mwi_sub->uniqueid, uniqueid)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  AST_LIST_REMOVE_CURRENT(entry);</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* Don't break here since a duplicate uniqueid</span><br><span style="color: hsl(0, 100%, 40%);">-                       * may have been added as a result of a cache dump. */</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef IMAP_STORAGE</span><br><span style="color: hsl(0, 100%, 40%);">-                       imap_logout(mwi_sub->mailbox);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-                 mwi_sub_destroy(mwi_sub);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_TRAVERSE_SAFE_END</span><br><span style="color: hsl(0, 100%, 40%);">-    AST_RWLIST_UNLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_free(uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_subscribe(void *datap)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned int len;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct mwi_sub *mwi_sub;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mwi_sub_task *p = datap;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- len = sizeof(*mwi_sub) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ast_strlen_zero(p->mailbox))</span><br><span style="color: hsl(0, 100%, 40%);">-            len += strlen(p->mailbox);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!ast_strlen_zero(p->context))</span><br><span style="color: hsl(0, 100%, 40%);">-            len += strlen(p->context) + 1; /* Allow for seperator */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!(mwi_sub = ast_calloc(1, len)))</span><br><span style="color: hsl(0, 100%, 40%);">-            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      mwi_sub->uniqueid = ast_strdup(p->uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!ast_strlen_zero(p->mailbox))</span><br><span style="color: hsl(0, 100%, 40%);">-            strcpy(mwi_sub->mailbox, p->mailbox);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ast_strlen_zero(p->context)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          strcat(mwi_sub->mailbox, "@");</span><br><span style="color: hsl(0, 100%, 40%);">-             strcat(mwi_sub->mailbox, p->context);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_WRLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry);</span><br><span style="color: hsl(0, 100%, 40%);">-  AST_RWLIST_UNLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       mwi_sub_task_dtor(p);</span><br><span style="color: hsl(0, 100%, 40%);">-   poll_subscribed_mailbox(mwi_sub);</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_unsub_event_cb(struct stasis_subscription_change *change)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    char *uniqueid = ast_strdup(change->uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!uniqueid) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_free(uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_sub_event_cb(struct stasis_subscription_change *change)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct mwi_sub_task *mwist;</span><br><span style="color: hsl(0, 100%, 40%);">-     char *context;</span><br><span style="color: hsl(0, 100%, 40%);">-  char *mailbox;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  mwist = ast_calloc(1, (sizeof(*mwist)));</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!mwist) {</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (separate_mailbox(ast_strdupa(stasis_topic_name(change->topic)), &mailbox, &context)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_free(mwist);</span><br><span style="color: hsl(0, 100%, 40%);">-                return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       mwist->mailbox = ast_strdup(mailbox);</span><br><span style="color: hsl(0, 100%, 40%);">-        mwist->context = ast_strdup(context);</span><br><span style="color: hsl(0, 100%, 40%);">-        mwist->uniqueid = ast_strdup(change->uniqueid);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             mwi_sub_task_dtor(mwist);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void mwi_event_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct stasis_subscription_change *change;</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Only looking for subscription change notices here */</span><br><span style="color: hsl(0, 100%, 40%);">- if (stasis_message_type(msg) != stasis_subscription_change_type()) {</span><br><span style="color: hsl(0, 100%, 40%);">-            return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       change = stasis_message_data(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (change->topic == ast_mwi_topic_all()) {</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!strcmp(change->description, "Subscribe")) {</span><br><span style="color: hsl(0, 100%, 40%);">-           mwi_sub_event_cb(change);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (!strcmp(change->description, "Unsubscribe")) {</span><br><span style="color: hsl(0, 100%, 40%);">-          mwi_unsub_event_cb(change);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int dump_cache(void *obj, void *arg, int flags)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct stasis_message *msg = obj;</span><br><span style="color: hsl(0, 100%, 40%);">-       mwi_event_cb(NULL, NULL, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-  return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void start_poll_thread(void)</span><br><span> {</span><br><span>       int errcode;</span><br><span style="color: hsl(0, 100%, 40%);">-    mwi_sub_sub = stasis_subscribe(ast_mwi_topic_all(), mwi_event_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (mwi_sub_sub) {</span><br><span style="color: hsl(0, 100%, 40%);">-              struct ao2_container *cached = stasis_cache_dump(ast_mwi_state_cache(), stasis_subscription_change_type());</span><br><span style="color: hsl(0, 100%, 40%);">-             if (cached) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   ao2_callback(cached, OBJ_MULTIPLE | OBJ_NODATA, dump_cache, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               ao2_cleanup(cached);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span> </span><br><span>        poll_thread_run = 1;</span><br><span> </span><br><span>@@ -13269,8 +13154,6 @@</span><br><span> {</span><br><span>      poll_thread_run = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        mwi_sub_sub = stasis_unsubscribe_and_join(mwi_sub_sub);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      ast_mutex_lock(&poll_lock);</span><br><span>      ast_cond_signal(&poll_cond);</span><br><span>     ast_mutex_unlock(&poll_lock);</span><br><span>@@ -13405,34 +13288,34 @@</span><br><span> {</span><br><span>   const char *context = astman_get_header(m, "Context");</span><br><span>     const char *mailbox = astman_get_header(m, "Mailbox");</span><br><span style="color: hsl(0, 100%, 40%);">-        struct mwi_sub *mwi_sub;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct poll_state *poll_state;</span><br><span>       const char *at;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     AST_RWLIST_RDLOCK(&mwi_subs);</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ast_strlen_zero(mwi_sub->mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_RWLIST_RDLOCK(&poll_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_RWLIST_TRAVERSE(&poll_list, poll_state, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!ast_strlen_zero(poll_state->mailbox)) {</span><br><span>                      if (</span><br><span>                                 /* First case: everything matches */</span><br><span>                                 (ast_strlen_zero(context) && ast_strlen_zero(mailbox)) ||</span><br><span>                            /* Second case: match the mailbox only */</span><br><span>                            (ast_strlen_zero(context) && !ast_strlen_zero(mailbox) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                                       (at = strchr(mwi_sub->mailbox, '@')) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                                      strncmp(mailbox, mwi_sub->mailbox, at - mwi_sub->mailbox) == 0) ||</span><br><span style="color: hsl(120, 100%, 40%);">+                                      (at = strchr(poll_state->mailbox, '@')) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                                 strncmp(mailbox, poll_state->mailbox, at - poll_state->mailbox) == 0) ||</span><br><span>                               /* Third case: match the context only */</span><br><span>                             (!ast_strlen_zero(context) && ast_strlen_zero(mailbox) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                                       (at = strchr(mwi_sub->mailbox, '@')) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                                    (at = strchr(poll_state->mailbox, '@')) &&</span><br><span>                                        strcmp(context, at + 1) == 0) ||</span><br><span>                             /* Final case: match an exact specified mailbox */</span><br><span>                           (!ast_strlen_zero(context) && !ast_strlen_zero(mailbox) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                                      (at = strchr(mwi_sub->mailbox, '@')) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                                      strncmp(mailbox, mwi_sub->mailbox, at - mwi_sub->mailbox) == 0 &&</span><br><span style="color: hsl(120, 100%, 40%);">+                                       (at = strchr(poll_state->mailbox, '@')) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                                 strncmp(mailbox, poll_state->mailbox, at - poll_state->mailbox) == 0 &&</span><br><span>                                        strcmp(context, at + 1) == 0)</span><br><span>                        ) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             poll_subscribed_mailbox(mwi_sub);</span><br><span style="color: hsl(120, 100%, 40%);">+                             poll_mailbox(poll_state);</span><br><span>                    }</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       AST_RWLIST_UNLOCK(&mwi_subs);</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_UNLOCK(&poll_list);</span><br><span>   astman_send_ack(s, m, "Refresh sent");</span><br><span>     return RESULT_SUCCESS;</span><br><span> }</span><br><span>@@ -13536,6 +13419,17 @@</span><br><span>       AST_LIST_UNLOCK(&users);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Free poll list. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void free_poll_list(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct poll_state *current;</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_RWLIST_WRLOCK(&poll_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    while ((current = AST_RWLIST_REMOVE_HEAD(&poll_list, entry))) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_free(current);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_RWLIST_UNLOCK(&poll_list);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Free the zones structure. */</span><br><span> static void free_vm_zones(void)</span><br><span> {</span><br><span>@@ -13653,8 +13547,6 @@</span><br><span>         int x;</span><br><span>       unsigned int tmpadsi[4];</span><br><span>     char secretfn[PATH_MAX] = "";</span><br><span style="color: hsl(0, 100%, 40%);">- long tps_queue_low;</span><br><span style="color: hsl(0, 100%, 40%);">-     long tps_queue_high;</span><br><span> </span><br><span> #ifdef IMAP_STORAGE</span><br><span>      ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder));</span><br><span>@@ -13670,12 +13562,20 @@</span><br><span>     imap_close_subscribed_mailboxes();</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      if (poll_thread != AST_PTHREADT_NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+               stop_poll_thread();</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Free the poll list */</span><br><span style="color: hsl(120, 100%, 40%);">+      free_poll_list();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Free all the users structure */</span><br><span>   free_vm_users();</span><br><span> </span><br><span>         /* Free all the zones structure */</span><br><span>   free_vm_zones();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  AST_RWLIST_WRLOCK(&poll_list);</span><br><span>   AST_LIST_LOCK(&users);</span><br><span> </span><br><span>       memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));</span><br><span>@@ -14243,23 +14143,11 @@</span><br><span>                   pagerbody = ast_strdup(substitute_escapes(val));</span><br><span>             }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           tps_queue_high = AST_TASKPROCESSOR_HIGH_WATER_LEVEL;</span><br><span>                 if ((val = ast_variable_retrieve(cfg, "general", "tps_queue_high"))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (sscanf(val, "%30ld", &tps_queue_high) != 1 || tps_queue_high <= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_log(AST_LOG_WARNING, "Invalid the taskprocessor high water alert trigger level '%s'\n", val);</span><br><span style="color: hsl(0, 100%, 40%);">-                             tps_queue_high = AST_TASKPROCESSOR_HIGH_WATER_LEVEL;</span><br><span style="color: hsl(0, 100%, 40%);">-                    }</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_log(LOG_NOTICE, "Parameter tps_queue_high is obsolete and will be ignored\n");</span><br><span>                 }</span><br><span style="color: hsl(0, 100%, 40%);">-               tps_queue_low = -1;</span><br><span>          if ((val = ast_variable_retrieve(cfg, "general", "tps_queue_low"))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (sscanf(val, "%30ld", &tps_queue_low) != 1 ||</span><br><span style="color: hsl(0, 100%, 40%);">-                          tps_queue_low < -1 || tps_queue_high < tps_queue_low) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           ast_log(AST_LOG_WARNING, "Invalid the taskprocessor low water clear alert level '%s'\n", val);</span><br><span style="color: hsl(0, 100%, 40%);">-                                tps_queue_low = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                     }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ast_taskprocessor_alert_set_levels(mwi_subscription_tps, tps_queue_low, tps_queue_high)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_log(AST_LOG_WARNING, "Failed to set alert levels for voicemail taskprocessor.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_NOTICE, "Parameter tps_queue_low is obsolete and will be ignored\n");</span><br><span>          }</span><br><span> </span><br><span>                /* load mailboxes from users.conf */</span><br><span>@@ -14329,15 +14217,15 @@</span><br><span>             }</span><br><span> </span><br><span>                AST_LIST_UNLOCK(&users);</span><br><span style="color: hsl(120, 100%, 40%);">+          AST_RWLIST_UNLOCK(&poll_list);</span><br><span> </span><br><span>               if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL)</span><br><span>                      start_poll_thread();</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-                        stop_poll_thread();;</span><br><span> </span><br><span>             return 0;</span><br><span>    } else {</span><br><span>             AST_LIST_UNLOCK(&users);</span><br><span style="color: hsl(120, 100%, 40%);">+          AST_RWLIST_UNLOCK(&poll_list);</span><br><span>           ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n");</span><br><span>          return 0;</span><br><span>    }</span><br><span>@@ -15065,13 +14953,13 @@</span><br><span>        if (poll_thread != AST_PTHREADT_NULL)</span><br><span>                stop_poll_thread();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps);</span><br><span>  ast_unload_realtime("voicemail");</span><br><span>  ast_unload_realtime("voicemail_data");</span><br><span> </span><br><span> #ifdef IMAP_STORAGE</span><br><span>  imap_close_subscribed_mailboxes();</span><br><span> #endif</span><br><span style="color: hsl(120, 100%, 40%);">+  free_poll_list();</span><br><span>    free_vm_users();</span><br><span>     free_vm_zones();</span><br><span>     return res;</span><br><span>@@ -15104,10 +14992,6 @@</span><br><span>       /* compute the location of the voicemail spool directory */</span><br><span>  snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor.  MWI will not work\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    if ((res = load_config(0))) {</span><br><span>                unload_module();</span><br><span>             return AST_MODULE_LOAD_DECLINE;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10135">change 10135</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10135"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5cceb737246949f9782955c64425b8bd25a9e9ee </div>
<div style="display:none"> Gerrit-Change-Number: 10135 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>