<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7763">View Change</a></p><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;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/63/7763/1</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: newchange </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>