1 /* stats.c - statistics from the bus driver
3 * Licensed under the Academic Free License version 2.1
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <dbus/dbus-internals.h>
25 #include <dbus/dbus-connection-internal.h>
27 #include "connection.h"
31 #ifdef DBUS_ENABLE_STATS
34 new_asv_reply (DBusMessage *message,
35 DBusMessageIter *iter,
36 DBusMessageIter *arr_iter)
38 DBusMessage *reply = dbus_message_new_method_return (message);
43 dbus_message_iter_init_append (reply, iter);
45 if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}",
48 dbus_message_unref (reply);
56 open_asv_entry (DBusMessageIter *arr_iter,
57 DBusMessageIter *entry_iter,
60 DBusMessageIter *var_iter)
62 if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY,
66 if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key))
68 dbus_message_iter_abandon_container (arr_iter, entry_iter);
72 if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT,
75 dbus_message_iter_abandon_container (arr_iter, entry_iter);
83 close_asv_entry (DBusMessageIter *arr_iter,
84 DBusMessageIter *entry_iter,
85 DBusMessageIter *var_iter)
87 if (!dbus_message_iter_close_container (entry_iter, var_iter))
89 dbus_message_iter_abandon_container (arr_iter, entry_iter);
93 if (!dbus_message_iter_close_container (arr_iter, entry_iter))
100 close_asv_reply (DBusMessageIter *iter,
101 DBusMessageIter *arr_iter)
103 return dbus_message_iter_close_container (iter, arr_iter);
107 abandon_asv_entry (DBusMessageIter *arr_iter,
108 DBusMessageIter *entry_iter,
109 DBusMessageIter *var_iter)
111 dbus_message_iter_abandon_container (entry_iter, var_iter);
112 dbus_message_iter_abandon_container (arr_iter, entry_iter);
116 abandon_asv_reply (DBusMessageIter *iter,
117 DBusMessageIter *arr_iter)
119 dbus_message_iter_abandon_container (iter, arr_iter);
123 asv_add_uint32 (DBusMessageIter *iter,
124 DBusMessageIter *arr_iter,
128 DBusMessageIter entry_iter, var_iter;
130 if (!open_asv_entry (arr_iter, &entry_iter, key, DBUS_TYPE_UINT32_AS_STRING,
134 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_UINT32,
137 abandon_asv_entry (arr_iter, &entry_iter, &var_iter);
141 if (!close_asv_entry (arr_iter, &entry_iter, &var_iter))
147 abandon_asv_reply (iter, arr_iter);
152 asv_add_string (DBusMessageIter *iter,
153 DBusMessageIter *arr_iter,
157 DBusMessageIter entry_iter, var_iter;
159 if (!open_asv_entry (arr_iter, &entry_iter, key, DBUS_TYPE_STRING_AS_STRING,
163 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_STRING,
166 abandon_asv_entry (arr_iter, &entry_iter, &var_iter);
170 if (!close_asv_entry (arr_iter, &entry_iter, &var_iter))
176 abandon_asv_reply (iter, arr_iter);
181 bus_stats_handle_get_stats (DBusConnection *connection,
182 BusTransaction *transaction,
183 DBusMessage *message,
186 BusConnections *connections;
187 DBusMessage *reply = NULL;
188 DBusMessageIter iter, arr_iter;
189 static dbus_uint32_t stats_serial = 0;
191 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
193 connections = bus_transaction_get_connections (transaction);
195 reply = new_asv_reply (message, &iter, &arr_iter);
200 if (!asv_add_uint32 (&iter, &arr_iter, "Serial", stats_serial++))
203 if (!close_asv_reply (&iter, &arr_iter))
206 if (!bus_transaction_send_from_driver (transaction, connection, reply))
209 dbus_message_unref (reply);
214 dbus_message_unref (reply);
221 bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
222 BusTransaction *transaction,
223 DBusMessage *message,
226 const char *bus_name = NULL;
227 DBusString bus_name_str;
228 DBusMessage *reply = NULL;
229 DBusMessageIter iter, arr_iter;
230 static dbus_uint32_t stats_serial = 0;
231 dbus_uint32_t in_messages, in_bytes, in_fds;
232 dbus_uint32_t out_messages, out_bytes, out_fds;
233 BusRegistry *registry;
235 DBusConnection *stats_connection;
237 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
239 registry = bus_connection_get_registry (caller_connection);
241 if (! dbus_message_get_args (message, error,
242 DBUS_TYPE_STRING, &bus_name,
246 _dbus_string_init_const (&bus_name_str, bus_name);
247 service = bus_registry_lookup (registry, &bus_name_str);
251 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
252 "Bus name '%s' has no owner", bus_name);
256 stats_connection = bus_service_get_primary_owners_connection (service);
257 _dbus_assert (stats_connection != NULL);
259 reply = new_asv_reply (message, &iter, &arr_iter);
264 if (!asv_add_uint32 (&iter, &arr_iter, "Serial", stats_serial++) ||
265 !asv_add_string (&iter, &arr_iter, "UniqueName",
266 bus_connection_get_name (stats_connection)))
269 if (!close_asv_reply (&iter, &arr_iter))
272 if (!bus_transaction_send_from_driver (transaction, caller_connection,
276 dbus_message_unref (reply);
281 dbus_message_unref (reply);