]> code.delx.au - pulseaudio/blob - src/modules/dbus/iface-memstats.c
Merge branch 'master' of git://0pointer.de/pulseaudio into dbus-work
[pulseaudio] / src / modules / dbus / iface-memstats.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2009 Tanu Kaskinen
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <dbus/dbus.h>
27
28 #include <pulsecore/core-scache.h>
29 #include <pulsecore/core-util.h>
30 #include <pulsecore/dbus-util.h>
31 #include <pulsecore/protocol-dbus.h>
32
33 #include "iface-memstats.h"
34
35 #define OBJECT_NAME "memstats"
36
37 static void handle_get_current_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata);
38 static void handle_get_current_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
39 static void handle_get_accumulated_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata);
40 static void handle_get_accumulated_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
41 static void handle_get_sample_cache_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
42
43 static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
44
45 struct pa_dbusiface_memstats {
46 pa_core *core;
47 char *path;
48 pa_dbus_protocol *dbus_protocol;
49 };
50
51 enum property_handler_index {
52 PROPERTY_HANDLER_CURRENT_MEMBLOCKS,
53 PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE,
54 PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS,
55 PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE,
56 PROPERTY_HANDLER_SAMPLE_CACHE_SIZE,
57 PROPERTY_HANDLER_MAX
58 };
59
60 static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
61 [PROPERTY_HANDLER_CURRENT_MEMBLOCKS] = { .property_name = "CurrentMemblocks", .type = "u", .get_cb = handle_get_current_memblocks, .set_cb = NULL },
62 [PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE] = { .property_name = "CurrentMemblocksSize", .type = "u", .get_cb = handle_get_current_memblocks_size, .set_cb = NULL },
63 [PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS] = { .property_name = "AccumulatedMemblocks", .type = "u", .get_cb = handle_get_accumulated_memblocks, .set_cb = NULL },
64 [PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE] = { .property_name = "AccumulatedMemblocksSize", .type = "u", .get_cb = handle_get_accumulated_memblocks_size, .set_cb = NULL },
65 [PROPERTY_HANDLER_SAMPLE_CACHE_SIZE] = { .property_name = "SampleCacheSize", .type = "u", .get_cb = handle_get_sample_cache_size, .set_cb = NULL }
66 };
67
68 static pa_dbus_interface_info memstats_interface_info = {
69 .name = PA_DBUSIFACE_MEMSTATS_INTERFACE,
70 .method_handlers = NULL,
71 .n_method_handlers = 0,
72 .property_handlers = property_handlers,
73 .n_property_handlers = PROPERTY_HANDLER_MAX,
74 .get_all_properties_cb = handle_get_all,
75 .signals = NULL,
76 .n_signals = 0
77 };
78
79 static void handle_get_current_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
80 pa_dbusiface_memstats *m = userdata;
81 const pa_mempool_stat *stat;
82 dbus_uint32_t current_memblocks;
83
84 pa_assert(conn);
85 pa_assert(msg);
86 pa_assert(m);
87
88 stat = pa_mempool_get_stat(m->core->mempool);
89
90 current_memblocks = pa_atomic_load(&stat->n_allocated);
91
92 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &current_memblocks);
93 }
94
95 static void handle_get_current_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
96 pa_dbusiface_memstats *m = userdata;
97 const pa_mempool_stat *stat;
98 dbus_uint32_t current_memblocks_size;
99
100 pa_assert(conn);
101 pa_assert(msg);
102 pa_assert(m);
103
104 stat = pa_mempool_get_stat(m->core->mempool);
105
106 current_memblocks_size = pa_atomic_load(&stat->allocated_size);
107
108 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &current_memblocks_size);
109 }
110
111 static void handle_get_accumulated_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
112 pa_dbusiface_memstats *m = userdata;
113 const pa_mempool_stat *stat;
114 dbus_uint32_t accumulated_memblocks;
115
116 pa_assert(conn);
117 pa_assert(msg);
118 pa_assert(m);
119
120 stat = pa_mempool_get_stat(m->core->mempool);
121
122 accumulated_memblocks = pa_atomic_load(&stat->n_accumulated);
123
124 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &accumulated_memblocks);
125 }
126
127 static void handle_get_accumulated_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
128 pa_dbusiface_memstats *m = userdata;
129 const pa_mempool_stat *stat;
130 dbus_uint32_t accumulated_memblocks_size;
131
132 pa_assert(conn);
133 pa_assert(msg);
134 pa_assert(m);
135
136 stat = pa_mempool_get_stat(m->core->mempool);
137
138 accumulated_memblocks_size = pa_atomic_load(&stat->accumulated_size);
139
140 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &accumulated_memblocks_size);
141 }
142
143 static void handle_get_sample_cache_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
144 pa_dbusiface_memstats *m = userdata;
145 dbus_uint32_t sample_cache_size;
146
147 pa_assert(conn);
148 pa_assert(msg);
149 pa_assert(m);
150
151 sample_cache_size = pa_scache_total_size(m->core);
152
153 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_cache_size);
154 }
155
156 static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
157 pa_dbusiface_memstats *m = userdata;
158 const pa_mempool_stat *stat;
159 dbus_uint32_t current_memblocks;
160 dbus_uint32_t current_memblocks_size;
161 dbus_uint32_t accumulated_memblocks;
162 dbus_uint32_t accumulated_memblocks_size;
163 dbus_uint32_t sample_cache_size;
164 DBusMessage *reply = NULL;
165 DBusMessageIter msg_iter;
166 DBusMessageIter dict_iter;
167
168 pa_assert(conn);
169 pa_assert(msg);
170 pa_assert(m);
171
172 stat = pa_mempool_get_stat(m->core->mempool);
173
174 current_memblocks = pa_atomic_load(&stat->n_allocated);
175 current_memblocks_size = pa_atomic_load(&stat->allocated_size);
176 accumulated_memblocks = pa_atomic_load(&stat->n_accumulated);
177 accumulated_memblocks_size = pa_atomic_load(&stat->accumulated_size);
178 sample_cache_size = pa_scache_total_size(m->core);
179
180 pa_assert_se((reply = dbus_message_new_method_return(msg)));
181
182 dbus_message_iter_init_append(reply, &msg_iter);
183 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
184
185 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CURRENT_MEMBLOCKS].property_name, DBUS_TYPE_UINT32, &current_memblocks);
186 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE].property_name, DBUS_TYPE_UINT32, &current_memblocks_size);
187 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS].property_name, DBUS_TYPE_UINT32, &accumulated_memblocks);
188 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE].property_name, DBUS_TYPE_UINT32, &accumulated_memblocks_size);
189 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_CACHE_SIZE].property_name, DBUS_TYPE_UINT32, &sample_cache_size);
190
191 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
192
193 pa_assert_se(dbus_connection_send(conn, reply, NULL));
194
195 dbus_message_unref(reply);
196 }
197
198 pa_dbusiface_memstats *pa_dbusiface_memstats_new(pa_dbusiface_core *dbus_core, pa_core *core) {
199 pa_dbusiface_memstats *m;
200
201 pa_assert(dbus_core);
202 pa_assert(core);
203
204 m = pa_xnew(pa_dbusiface_memstats, 1);
205 m->core = pa_core_ref(core);
206 m->path = pa_sprintf_malloc("%s/%s", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME);
207 m->dbus_protocol = pa_dbus_protocol_get(core);
208
209 pa_assert_se(pa_dbus_protocol_add_interface(m->dbus_protocol, m->path, &memstats_interface_info, m) >= 0);
210
211 return m;
212 }
213
214 void pa_dbusiface_memstats_free(pa_dbusiface_memstats *m) {
215 pa_assert(m);
216
217 pa_assert_se(pa_dbus_protocol_remove_interface(m->dbus_protocol, m->path, memstats_interface_info.name) >= 0);
218
219 pa_xfree(m->path);
220
221 pa_dbus_protocol_unref(m->dbus_protocol);
222 pa_core_unref(m->core);
223
224 pa_xfree(m);
225 }
226
227 const char *pa_dbusiface_memstats_get_path(pa_dbusiface_memstats *m) {
228 pa_assert(m);
229
230 return m->path;
231 }