+ call_rcu(&ua_chan->rcu_head, delete_ust_app_channel_rcu);
+}
+
+/*
+ * Push metadata to consumer socket. The socket lock MUST be acquired.
+ *
+ * On success, return the len of metadata pushed or else a negative value.
+ */
+ssize_t ust_app_push_metadata(struct ust_registry_session *registry,
+ struct consumer_socket *socket, int send_zero_data)
+{
+ int ret;
+ char *metadata_str = NULL;
+ size_t len, offset;
+ ssize_t ret_val;
+
+ assert(registry);
+ assert(socket);
+ /* Should never be 0 which is the initial state. */
+ assert(registry->metadata_key);
+
+ pthread_mutex_lock(®istry->lock);
+
+ offset = registry->metadata_len_sent;
+ len = registry->metadata_len - registry->metadata_len_sent;
+ if (len == 0) {
+ DBG3("No metadata to push for metadata key %" PRIu64,
+ registry->metadata_key);
+ ret_val = len;
+ if (send_zero_data) {
+ DBG("No metadata to push");
+ goto push_data;
+ }
+ goto end;
+ }
+
+ /* Allocate only what we have to send. */
+ metadata_str = zmalloc(len);
+ if (!metadata_str) {
+ PERROR("zmalloc ust app metadata string");
+ ret_val = -ENOMEM;
+ goto error;
+ }
+ /* Copy what we haven't send out. */
+ memcpy(metadata_str, registry->metadata + offset, len);
+ registry->metadata_len_sent += len;
+
+push_data:
+ pthread_mutex_unlock(®istry->lock);
+ ret = consumer_push_metadata(socket, registry->metadata_key,
+ metadata_str, len, offset);
+ if (ret < 0) {
+ ret_val = ret;
+ goto error_push;
+ }
+
+ free(metadata_str);
+ return len;
+
+end:
+error:
+ pthread_mutex_unlock(®istry->lock);
+error_push:
+ free(metadata_str);
+ return ret_val;