<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/7763">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Corey Farrell: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">stasis_channels.c: Misc cleanup.<br><br>* Use current OBJ_SEARCH_xxx defines instead of the deprecated versions.<br><br>* Fix hash_cb and cmp_cb container functions to correctly use the<br>OBJ_SEARCH_xxx values.<br><br>* Remove incorrect usage of CMP_STOP.  Most uses in the system have no<br>effect.  This allows the collapse of channel_role_single_cmp_cb() and<br>channel_role_multi_cmp_cb() into channel_role_cmp_cb().<br><br>* Remove unnecessary usage of RAII_VAR().<br><br>Change-Id: I02c405518cab22aa2a082b61e2353bf7cd629a70<br>---<br>M main/stasis_channels.c<br>1 file changed, 193 insertions(+), 119 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/stasis_channels.c b/main/stasis_channels.c<br>index 293db06..8041c8e 100644<br>--- a/main/stasis_channels.c<br>+++ b/main/stasis_channels.c<br>@@ -172,9 +172,21 @@<br>  */<br> static int channel_snapshot_hash_cb(const void *obj, const int flags)<br> {<br>-  const struct ast_channel_snapshot *snapshot = obj;<br>-   const char *name = (flags & OBJ_KEY) ? obj : snapshot->name;<br>-  return ast_str_case_hash(name);<br>+      const struct ast_channel_snapshot *object = obj;<br>+     const char *key;<br>+<br>+  switch (flags & OBJ_SEARCH_MASK) {<br>+       case OBJ_SEARCH_KEY:<br>+         key = obj;<br>+           break;<br>+       case OBJ_SEARCH_OBJECT:<br>+              key = object->name;<br>+               break;<br>+       default:<br>+             ast_assert(0);<br>+               return 0;<br>+    }<br>+    return ast_str_case_hash(key);<br> }<br> <br> /*!<br>@@ -183,10 +195,28 @@<br>  */<br> static int channel_snapshot_cmp_cb(void *obj, void *arg, int flags)<br> {<br>-   struct ast_channel_snapshot *left = obj;<br>-     struct ast_channel_snapshot *right = arg;<br>-    const char *match = (flags & OBJ_KEY) ? arg : right->name;<br>-    return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP);<br>+        const struct ast_channel_snapshot *object_left = obj;<br>+        const struct ast_channel_snapshot *object_right = arg;<br>+       const char *right_key = arg;<br>+ int cmp;<br>+<br>+  switch (flags & OBJ_SEARCH_MASK) {<br>+       case OBJ_SEARCH_OBJECT:<br>+              right_key = object_right->name;<br>+   case OBJ_SEARCH_KEY:<br>+         cmp = strcasecmp(object_left->name, right_key);<br>+           break;<br>+       case OBJ_SEARCH_PARTIAL_KEY:<br>+         cmp = strncasecmp(object_left->name, right_key, strlen(right_key));<br>+               break;<br>+       default:<br>+             cmp = 0;<br>+             break;<br>+       }<br>+    if (cmp) {<br>+           return 0;<br>+    }<br>+    return CMP_MATCH;<br> }<br> <br> static void channel_snapshot_dtor(void *obj)<br>@@ -299,31 +329,33 @@<br>        struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring,<br>      const char *dialstatus, const char *forward)<br> {<br>-     RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);<br>-       RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);<br>-   RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);<br>-     RAII_VAR(struct ast_channel_snapshot *, caller_snapshot, NULL, ao2_cleanup);<br>- RAII_VAR(struct ast_channel_snapshot *, peer_snapshot, NULL, ao2_cleanup);<br>-   RAII_VAR(struct ast_channel_snapshot *, forwarded_snapshot, NULL, ao2_cleanup);<br>+      struct ast_multi_channel_blob *payload;<br>+      struct stasis_message *msg;<br>+  struct ast_json *blob;<br>+       struct ast_channel_snapshot *peer_snapshot;<br> <br>        if (!ast_channel_dial_type()) {<br>               return;<br>       }<br> <br>  ast_assert(peer != NULL);<br>+<br>  blob = ast_json_pack("{s: s, s: s, s: s}",<br>-                      "dialstatus", S_OR(dialstatus, ""),<br>-                      "forward", S_OR(forward, ""),<br>-                            "dialstring", S_OR(dialstring, ""));<br>+                "dialstatus", S_OR(dialstatus, ""),<br>+              "forward", S_OR(forward, ""),<br>+            "dialstring", S_OR(dialstring, ""));<br>      if (!blob) {<br>          return;<br>       }<br>     payload = ast_multi_channel_blob_create(blob);<br>+       ast_json_unref(blob);<br>         if (!payload) {<br>               return;<br>       }<br> <br>  if (caller) {<br>+                struct ast_channel_snapshot *caller_snapshot;<br>+<br>              ast_channel_lock(caller);<br>             if (ast_strlen_zero(dialstatus)) {<br>                    caller_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(caller));<br>@@ -332,9 +364,11 @@<br>                }<br>             ast_channel_unlock(caller);<br>           if (!caller_snapshot) {<br>+                      ao2_ref(payload, -1);<br>                         return;<br>               }<br>             ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot);<br>+            ao2_ref(caller_snapshot, -1);<br>         }<br> <br>  ast_channel_lock(peer);<br>@@ -345,26 +379,32 @@<br>        }<br>     ast_channel_unlock(peer);<br>     if (!peer_snapshot) {<br>+                ao2_ref(payload, -1);<br>                 return;<br>       }<br>     ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot);<br>+        ao2_ref(peer_snapshot, -1);<br> <br>        if (forwarded) {<br>+             struct ast_channel_snapshot *forwarded_snapshot;<br>+<br>           ast_channel_lock(forwarded);<br>          forwarded_snapshot = ast_channel_snapshot_create(forwarded);<br>          ast_channel_unlock(forwarded);<br>                if (!forwarded_snapshot) {<br>+                   ao2_ref(payload, -1);<br>                         return;<br>               }<br>             ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot);<br>+              ao2_ref(forwarded_snapshot, -1);<br>      }<br> <br>  msg = stasis_message_create(ast_channel_dial_type(), payload);<br>-       if (!msg) {<br>-          return;<br>+      ao2_ref(payload, -1);<br>+        if (msg) {<br>+           publish_message_for_channel_topics(msg, caller ?: peer);<br>+             ao2_ref(msg, -1);<br>     }<br>-<br>- publish_message_for_channel_topics(msg, caller ?: peer);<br> }<br> <br> static void remove_dial_masquerade(struct ast_channel *peer);<br>@@ -458,33 +498,33 @@<br>                                               struct stasis_message_type *type,<br>                                             struct ast_json *blob)<br> {<br>-    RAII_VAR(struct ast_channel_snapshot *, snapshot,<br>-                    NULL,<br>-                        ao2_cleanup);<br>+        struct ast_channel_snapshot *snapshot;<br>+       struct stasis_message *msg;<br> <br>        if (!type) {<br>          return NULL;<br>  }<br> <br>  snapshot = ast_channel_snapshot_get_latest(channel_id);<br>-<br>-   return create_channel_blob_message(snapshot, type, blob);<br>+    msg = create_channel_blob_message(snapshot, type, blob);<br>+     ao2_cleanup(snapshot);<br>+       return msg;<br> }<br> <br> struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,<br>         struct stasis_message_type *type, struct ast_json *blob)<br> {<br>- RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);<br>+        struct ast_channel_snapshot *snapshot;<br>+       struct stasis_message *msg;<br> <br>        if (!type) {<br>          return NULL;<br>  }<br> <br>- if (chan) {<br>-          snapshot = ast_channel_snapshot_create(chan);<br>-        }<br>-<br>- return create_channel_blob_message(snapshot, type, blob);<br>+    snapshot = chan ? ast_channel_snapshot_create(chan) : NULL;<br>+  msg = create_channel_blob_message(snapshot, type, blob);<br>+     ao2_cleanup(snapshot);<br>+       return msg;<br> }<br> <br> /*! \brief A channel snapshot wrapper object used in \ref ast_multi_channel_blob objects */<br>@@ -496,31 +536,37 @@<br> /*! \brief A multi channel blob data structure for multi_channel_blob stasis messages */<br> struct ast_multi_channel_blob {<br>  struct ao2_container *channel_snapshots;        /*!< A container holding the snapshots */<br>- struct ast_json *blob;                                          /*< A blob of JSON data */<br>+        struct ast_json *blob;                                          /*!< A blob of JSON data */<br> };<br> <br> /*!<br>  * \internal<br>- * \brief Standard comparison function for \ref channel_role_snapshot objects<br>+ * \brief Comparison function for \ref channel_role_snapshot objects<br>  */<br>-static int channel_role_single_cmp_cb(void *obj, void *arg, int flags)<br>+static int channel_role_cmp_cb(void *obj, void *arg, int flags)<br> {<br>-      struct channel_role_snapshot *left = obj;<br>-    struct channel_role_snapshot *right = arg;<br>-   const char *match = (flags & OBJ_KEY) ? arg : right->role;<br>-    return strcasecmp(left->role, match) ? 0 : (CMP_MATCH | CMP_STOP);<br>-}<br>+    const struct channel_role_snapshot *object_left = obj;<br>+       const struct channel_role_snapshot *object_right = arg;<br>+      const char *right_key = arg;<br>+ int cmp;<br> <br>-/*!<br>- * \internal<br>- * \brief Multi comparison function for \ref channel_role_snapshot objects<br>- */<br>-static int channel_role_multi_cmp_cb(void *obj, void *arg, int flags)<br>-{<br>-      struct channel_role_snapshot *left = obj;<br>-    struct channel_role_snapshot *right = arg;<br>-   const char *match = (flags & OBJ_KEY) ? arg : right->role;<br>-    return strcasecmp(left->role, match) ? 0 : (CMP_MATCH);<br>+   switch (flags & OBJ_SEARCH_MASK) {<br>+       case OBJ_SEARCH_OBJECT:<br>+              right_key = object_right->role;<br>+   case OBJ_SEARCH_KEY:<br>+         cmp = strcasecmp(object_left->role, right_key);<br>+           break;<br>+       case OBJ_SEARCH_PARTIAL_KEY:<br>+         cmp = strncasecmp(object_left->role, right_key, strlen(right_key));<br>+               break;<br>+       default:<br>+             cmp = 0;<br>+             break;<br>+       }<br>+    if (cmp) {<br>+           return 0;<br>+    }<br>+    return CMP_MATCH;<br> }<br> <br> /*!<br>@@ -529,9 +575,21 @@<br>  */<br> static int channel_role_hash_cb(const void *obj, const int flags)<br> {<br>-   const struct channel_role_snapshot *snapshot = obj;<br>-  const char *name = (flags & OBJ_KEY) ? obj : snapshot->role;<br>-  return ast_str_case_hash(name);<br>+      const struct channel_role_snapshot *object = obj;<br>+    const char *key;<br>+<br>+  switch (flags & OBJ_SEARCH_MASK) {<br>+       case OBJ_SEARCH_KEY:<br>+         key = obj;<br>+           break;<br>+       case OBJ_SEARCH_OBJECT:<br>+              key = object->role;<br>+               break;<br>+       default:<br>+             ast_assert(0);<br>+               return 0;<br>+    }<br>+    return ast_str_case_hash(key);<br> }<br> <br> /*!<br>@@ -548,89 +606,80 @@<br> <br> struct ast_multi_channel_blob *ast_multi_channel_blob_create(struct ast_json *blob)<br> {<br>-      RAII_VAR(struct ast_multi_channel_blob *, obj,<br>-                       ao2_alloc(sizeof(*obj), multi_channel_blob_dtor),<br>-                    ao2_cleanup);<br>+        struct ast_multi_channel_blob *obj;<br> <br>        ast_assert(blob != NULL);<br> <br>+ obj = ao2_alloc(sizeof(*obj), multi_channel_blob_dtor);<br>       if (!obj) {<br>           return NULL;<br>  }<br> <br>  obj->channel_snapshots = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS,<br>-                      channel_role_hash_cb, channel_role_single_cmp_cb);<br>+           channel_role_hash_cb, channel_role_cmp_cb);<br>   if (!obj->channel_snapshots) {<br>+            ao2_ref(obj, -1);<br>             return NULL;<br>  }<br> <br>  obj->blob = ast_json_ref(blob);<br>-<br>-        ao2_ref(obj, +1);<br>     return obj;<br> }<br> <br> struct ast_channel_snapshot *ast_channel_snapshot_get_latest(const char *uniqueid)<br> {<br>-  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);<br>+       struct stasis_message *message;<br>       struct ast_channel_snapshot *snapshot;<br> <br>     ast_assert(!ast_strlen_zero(uniqueid));<br> <br>-   message = stasis_cache_get(ast_channel_cache(),<br>-                      ast_channel_snapshot_type(),<br>-                 uniqueid);<br>+   message = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(),<br>+         uniqueid);<br>    if (!message) {<br>               return NULL;<br>  }<br> <br>- snapshot = stasis_message_data(message);<br>-     if (!snapshot) {<br>-             return NULL;<br>- }<br>-    ao2_ref(snapshot, +1);<br>+       snapshot = ao2_bump(stasis_message_data(message));<br>+   ao2_ref(message, -1);<br>         return snapshot;<br> }<br> <br> struct ast_channel_snapshot *ast_channel_snapshot_get_latest_by_name(const char *name)<br> {<br>- RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);<br>+       struct stasis_message *message;<br>       struct ast_channel_snapshot *snapshot;<br> <br>     ast_assert(!ast_strlen_zero(name));<br> <br>-       message = stasis_cache_get(ast_channel_cache_by_name(),<br>-                      ast_channel_snapshot_type(),<br>-                 name);<br>+       message = stasis_cache_get(ast_channel_cache_by_name(), ast_channel_snapshot_type(),<br>+         name);<br>        if (!message) {<br>               return NULL;<br>  }<br> <br>- snapshot = stasis_message_data(message);<br>-     if (!snapshot) {<br>-             return NULL;<br>- }<br>-    ao2_ref(snapshot, +1);<br>+       snapshot = ao2_bump(stasis_message_data(message));<br>+   ao2_ref(message, -1);<br>         return snapshot;<br> }<br> <br> static void channel_role_snapshot_dtor(void *obj)<br> {<br>       struct channel_role_snapshot *role_snapshot = obj;<br>+<br>         ao2_cleanup(role_snapshot->snapshot);<br> }<br> <br> void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)<br> {<br>-   RAII_VAR(struct channel_role_snapshot *, role_snapshot, NULL, ao2_cleanup);<br>+  struct channel_role_snapshot *role_snapshot;<br>  int role_len = strlen(role) + 1;<br> <br>   if (!obj || ast_strlen_zero(role) || !snapshot) {<br>             return;<br>       }<br> <br>- role_snapshot = ao2_alloc_options(sizeof(*role_snapshot) + role_len, channel_role_snapshot_dtor,<br>-             AO2_ALLOC_OPT_LOCK_NOLOCK);<br>+  role_snapshot = ao2_alloc_options(sizeof(*role_snapshot) + role_len,<br>+         channel_role_snapshot_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);<br>       if (!role_snapshot) {<br>                 return;<br>       }<br>@@ -638,40 +687,49 @@<br>      role_snapshot->snapshot = snapshot;<br>        ao2_ref(role_snapshot->snapshot, +1);<br>      ao2_link(obj->channel_snapshots, role_snapshot);<br>+  ao2_ref(role_snapshot, -1);<br> }<br> <br> struct ast_channel_snapshot *ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)<br> {<br>        struct channel_role_snapshot *role_snapshot;<br>+ struct ast_channel_snapshot *snapshot;<br> <br>     if (!obj || ast_strlen_zero(role)) {<br>          return NULL;<br>  }<br>-    role_snapshot = ao2_find(obj->channel_snapshots, role, OBJ_KEY);<br>+  role_snapshot = ao2_find(obj->channel_snapshots, role, OBJ_SEARCH_KEY);<br>    /* Note that this function does not increase the ref count on snapshot */<br>     if (!role_snapshot) {<br>                 return NULL;<br>  }<br>+    snapshot = role_snapshot->snapshot;<br>        ao2_ref(role_snapshot, -1);<br>-  return role_snapshot->snapshot;<br>+   return snapshot;<br> }<br> <br> struct ao2_container *ast_multi_channel_blob_get_channels(struct ast_multi_channel_blob *obj, const char *role)<br> {<br>-        RAII_VAR(struct ao2_container *, ret_container,<br>-              ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_snapshot_hash_cb, channel_snapshot_cmp_cb),<br>-              ao2_cleanup);<br>+        struct ao2_container *ret_container;<br>  struct ao2_iterator *it_role_snapshots;<br>       struct channel_role_snapshot *role_snapshot;<br>  char *arg;<br> <br>-        if (!obj || ast_strlen_zero(role) || !ret_container) {<br>+       if (!obj || ast_strlen_zero(role)) {<br>          return NULL;<br>  }<br>-    arg = ast_strdupa(role);<br> <br>-  it_role_snapshots = ao2_callback(obj->channel_snapshots, OBJ_MULTIPLE | OBJ_KEY, channel_role_multi_cmp_cb, arg);<br>+ ret_container = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS,<br>+          channel_snapshot_hash_cb, channel_snapshot_cmp_cb);<br>+  if (!ret_container) {<br>+                return NULL;<br>+ }<br>+<br>+ arg = ast_strdupa(role);<br>+     it_role_snapshots = ao2_callback(obj->channel_snapshots,<br>+          OBJ_MULTIPLE | OBJ_SEARCH_KEY, channel_role_cmp_cb, arg);<br>     if (!it_role_snapshots) {<br>+            ao2_ref(ret_container, -1);<br>           return NULL;<br>  }<br> <br>@@ -681,7 +739,6 @@<br>     }<br>     ao2_iterator_destroy(it_role_snapshots);<br> <br>-  ao2_ref(ret_container, +1);<br>   return ret_container;<br> }<br> <br>@@ -706,8 +763,8 @@<br> <br> void ast_channel_publish_snapshot(struct ast_channel *chan)<br> {<br>-       RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);<br>-        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);<br>+       struct ast_channel_snapshot *snapshot;<br>+       struct stasis_message *message;<br> <br>    if (!ast_channel_snapshot_type()) {<br>           return;<br>@@ -723,12 +780,14 @@<br>        }<br> <br>  message = stasis_message_create(ast_channel_snapshot_type(), snapshot);<br>+      ao2_ref(snapshot, -1);<br>        if (!message) {<br>               return;<br>       }<br> <br>  ast_assert(ast_channel_topic(chan) != NULL);<br>  stasis_publish(ast_channel_topic(chan), message);<br>+    ao2_ref(message, -1);<br> }<br> <br> void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)<br>@@ -742,8 +801,8 @@<br>   message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), type, blob);<br>         if (message) {<br>                stasis_publish(ast_channel_topic(chan), message);<br>+            ao2_ref(message, -1);<br>         }<br>-    ao2_cleanup(message);<br> }<br> <br> void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)<br>@@ -757,8 +816,8 @@<br>  message = ast_channel_blob_create(chan, type, blob);<br>  if (message) {<br>                stasis_publish(ast_channel_topic(chan), message);<br>+            ao2_ref(message, -1);<br>         }<br>-    ao2_cleanup(message);<br> }<br> <br> void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value)<br>@@ -793,78 +852,88 @@<br> <br> static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg)<br> {<br>-        RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);<br>+    struct ast_str *channel_event_string;<br>         struct ast_channel_blob *obj = stasis_message_data(msg);<br>      const char *variable =<br>                ast_json_string_get(ast_json_object_get(obj->blob, "variable"));<br>-        RAII_VAR(char *, value, ast_escape_c_alloc(<br>-                   ast_json_string_get(ast_json_object_get(obj->blob, "value"))), ast_free);<br>+      char *value;<br>+ struct ast_manager_event_blob *ev;<br> <br>+        value = ast_escape_c_alloc(ast_json_string_get(ast_json_object_get(obj->blob,<br>+             "value")));<br>         if (!value) {<br>                 return NULL;<br>  }<br> <br>  if (obj->snapshot) {<br>-              channel_event_string =<br>-                       ast_manager_build_channel_state_string(obj->snapshot);<br>+            channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);<br>      } else {<br>              channel_event_string = ast_str_create(35);<br>            ast_str_set(&channel_event_string, 0,<br>-                        "Channel: none\r\n"<br>-                        "Uniqueid: none\r\n");<br>+                 "Channel: none\r\n"<br>+                        "Uniqueid: none\r\n");<br>      }<br>-<br>  if (!channel_event_string) {<br>+         ast_free(value);<br>              return NULL;<br>  }<br> <br>- return ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet",<br>+        ev = ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet",<br>           "%s"<br>                "Variable: %s\r\n"<br>          "Value: %s\r\n",<br>            ast_str_buffer(channel_event_string), variable, value);<br>+      ast_free(channel_event_string);<br>+      ast_free(value);<br>+     return ev;<br> }<br> <br> static struct ast_manager_event_blob *agent_login_to_ami(struct stasis_message *msg)<br> {<br>- RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);<br>+  struct ast_str *channel_string;<br>       struct ast_channel_blob *obj = stasis_message_data(msg);<br>      const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));<br>+       struct ast_manager_event_blob *ev;<br> <br>         channel_string = ast_manager_build_channel_state_string(obj->snapshot);<br>    if (!channel_string) {<br>                return NULL;<br>  }<br> <br>- return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin",<br>+       ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin",<br>          "%s"<br>                "Agent: %s\r\n",<br>            ast_str_buffer(channel_string), agent);<br>+      ast_free(channel_string);<br>+    return ev;<br> }<br> <br> static struct ast_manager_event_blob *agent_logoff_to_ami(struct stasis_message *msg)<br> {<br>-        RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);<br>+  struct ast_str *channel_string;<br>       struct ast_channel_blob *obj = stasis_message_data(msg);<br>      const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));<br>        long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime"));<br>+     struct ast_manager_event_blob *ev;<br> <br>         channel_string = ast_manager_build_channel_state_string(obj->snapshot);<br>    if (!channel_string) {<br>                return NULL;<br>  }<br> <br>- return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff",<br>+      ev = ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff",<br>                 "%s"<br>                "Agent: %s\r\n"<br>             "Logintime: %ld\r\n",<br>               ast_str_buffer(channel_string), agent, logintime);<br>+   ast_free(channel_string);<br>+    return ev;<br> }<br> <br> void ast_publish_channel_state(struct ast_channel *chan)<br> {<br>-     RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);<br>-        RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);<br>+       struct ast_channel_snapshot *snapshot;<br>+       struct stasis_message *message;<br> <br>    if (!ast_channel_snapshot_type()) {<br>           return;<br>@@ -881,12 +950,14 @@<br>        }<br> <br>  message = stasis_message_create(ast_channel_snapshot_type(), snapshot);<br>+      ao2_ref(snapshot, -1);<br>        if (!message) {<br>               return;<br>       }<br> <br>  ast_assert(ast_channel_topic(chan) != NULL);<br>  stasis_publish(ast_channel_topic(chan), message);<br>+    ao2_ref(message, -1);<br> }<br> <br> struct ast_json *ast_channel_snapshot_to_json(<br>@@ -896,8 +967,9 @@<br>    struct ast_json *json_chan;<br> <br>        if (snapshot == NULL<br>-         || (sanitize && sanitize->channel_snapshot<br>-                && sanitize->channel_snapshot(snapshot))) {<br>+               || (sanitize<br>+                 && sanitize->channel_snapshot<br>+                     && sanitize->channel_snapshot(snapshot))) {<br>                return NULL;<br>  }<br> <br>@@ -975,7 +1047,7 @@<br>    const char *type,<br>     const struct stasis_message_sanitizer *sanitize)<br> {<br>- RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);<br>+      struct ast_json *to_json;<br>     struct ast_channel_blob *channel_blob = stasis_message_data(message);<br>         struct ast_json *blob = channel_blob->blob;<br>        struct ast_channel_snapshot *snapshot = channel_blob->snapshot;<br>@@ -983,36 +1055,38 @@<br>    int res = 0;<br> <br>       if (blob == NULL || ast_json_is_null(blob)) {<br>-                out = ast_json_object_create();<br>+              to_json = ast_json_object_create();<br>   } else {<br>              /* blobs are immutable, so shallow copies are fine */<br>-                out = ast_json_copy(blob);<br>+           to_json = ast_json_copy(blob);<br>        }<br>-<br>- if (!out) {<br>+  if (!to_json) {<br>               return NULL;<br>  }<br> <br>- res |= ast_json_object_set(out, "type", ast_json_string_create(type));<br>-     res |= ast_json_object_set(out, "timestamp",<br>+       res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));<br>+ res |= ast_json_object_set(to_json, "timestamp",<br>            ast_json_timeval(*tv, NULL));<br> <br>      /* For global channel messages, the snapshot is optional */<br>   if (snapshot) {<br>-              struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);<br>+            struct ast_json *json_channel;<br> <br>+            json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);<br>              if (!json_channel) {<br>+                 ast_json_unref(to_json);<br>                      return NULL;<br>          }<br> <br>-         res |= ast_json_object_set(out, "channel", json_channel);<br>+          res |= ast_json_object_set(to_json, "channel", json_channel);<br>       }<br> <br>  if (res != 0) {<br>+              ast_json_unref(to_json);<br>              return NULL;<br>  }<br> <br>- return ast_json_ref(out);<br>+    return to_json;<br> }<br> <br> static struct ast_json *dtmf_end_to_json(<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7763">change 7763</a>. To unsubscribe, 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/7763"/><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: merged </div>
<div style="display:none"> Gerrit-Change-Id: I02c405518cab22aa2a082b61e2353bf7cd629a70 </div>
<div style="display:none"> Gerrit-Change-Number: 7763 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>