+ filter_key = notif->key;
+ side_statedump_event_call(side_statedump_begin,
+ side_arg_list(side_arg_string(handle->name)));
+ handle->cb();
+ side_statedump_event_call(side_statedump_end,
+ side_arg_list(side_arg_string(handle->name)));
+ filter_key = SIDE_KEY_MATCH_ALL;
+}
+
+static
+void _side_statedump_run_pending_requests(struct side_statedump_request_handle *handle)
+{
+ struct side_statedump_notification *notif, *tmp;
+ DEFINE_SIDE_LIST_HEAD(tmp_head);
+
+ pthread_mutex_lock(&side_statedump_lock);
+ side_list_splice(&handle->notification_queue, &tmp_head);
+ pthread_mutex_lock(&side_statedump_lock);
+
+ /* We are now sole owner of the tmp_head list. */
+ side_list_for_each_entry(notif, &tmp_head, node)
+ side_statedump_run(handle, notif);
+ side_list_for_each_entry_safe(notif, tmp, &tmp_head, node)
+ free(notif);
+}
+
+/*
+ * Only polling mode state dump handles allow application to explicitly handle the
+ * pending requests.
+ */
+int side_statedump_run_pending_requests(struct side_statedump_request_handle *handle)
+{
+ if (handle->mode != SIDE_STATEDUMP_MODE_POLLING)
+ return SIDE_ERROR_INVAL;
+ _side_statedump_run_pending_requests(handle);
+ return SIDE_ERROR_OK;
+}
+
+/*
+ * Request a state dump for tracer callbacks identified with "key".
+ */
+int side_tracer_statedump_request(uint64_t key)
+{
+ struct side_statedump_request_handle *handle;
+
+ if (key == SIDE_KEY_MATCH_ALL)
+ return SIDE_ERROR_INVAL;
+ pthread_mutex_lock(&side_statedump_lock);
+ side_list_for_each_entry(handle, &side_statedump_list, node)
+ queue_statedump_pending(handle, key);
+ pthread_mutex_lock(&side_statedump_lock);
+ return SIDE_ERROR_OK;
+}
+
+/*
+ * Cancel a statedump request.
+ */
+int side_tracer_statedump_request_cancel(uint64_t key)
+{
+ struct side_statedump_request_handle *handle;
+
+ if (key == SIDE_KEY_MATCH_ALL)
+ return SIDE_ERROR_INVAL;
+ pthread_mutex_lock(&side_statedump_lock);
+ side_list_for_each_entry(handle, &side_statedump_list, node)
+ unqueue_statedump_pending(handle, key);
+ pthread_mutex_lock(&side_statedump_lock);
+ return SIDE_ERROR_OK;
+}
+
+/*
+ * Tracer keys are represented on 64-bit. Return SIDE_ERROR_NOMEM on
+ * overflow (which should never happen in practice).
+ */
+int side_tracer_request_key(uint64_t *key)
+{
+ int ret = SIDE_ERROR_OK;
+
+ pthread_mutex_lock(&side_key_lock);
+ if (side_key_next == 0) {
+ ret = SIDE_ERROR_NOMEM;
+ goto end;
+ }
+ *key = side_key_next++;
+end:
+ pthread_mutex_unlock(&side_key_lock);
+ return ret;