Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: webrtc/base/dbus.cc

Issue 2520533002: Remove unused dbus.cc/.h and related things. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/dbus.h ('k') | webrtc/base/dbus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifdef HAVE_DBUS_GLIB
12
13 #include "webrtc/base/dbus.h"
14
15 #include <glib.h>
16
17 #include "webrtc/base/logging.h"
18 #include "webrtc/base/thread.h"
19
20 namespace rtc {
21
22 // Avoid static object construction/destruction on startup/shutdown.
23 static pthread_once_t g_dbus_init_once = PTHREAD_ONCE_INIT;
24 static LibDBusGlibSymbolTable *g_dbus_symbol = NULL;
25
26 // Releases DBus-Glib symbols.
27 static void ReleaseDBusGlibSymbol() {
28 if (g_dbus_symbol != NULL) {
29 delete g_dbus_symbol;
30 g_dbus_symbol = NULL;
31 }
32 }
33
34 // Loads DBus-Glib symbols.
35 static void InitializeDBusGlibSymbol() {
36 // This is thread safe.
37 if (NULL == g_dbus_symbol) {
38 g_dbus_symbol = new LibDBusGlibSymbolTable();
39
40 // Loads dbus-glib
41 if (NULL == g_dbus_symbol || !g_dbus_symbol->Load()) {
42 LOG(LS_WARNING) << "Failed to load dbus-glib symbol table.";
43 ReleaseDBusGlibSymbol();
44 } else {
45 // Nothing we can do if atexit() failed. Just ignore its returned value.
46 atexit(ReleaseDBusGlibSymbol);
47 }
48 }
49 }
50
51 inline static LibDBusGlibSymbolTable *GetSymbols() {
52 return DBusMonitor::GetDBusGlibSymbolTable();
53 }
54
55 // Implementation of class DBusSigMessageData
56 DBusSigMessageData::DBusSigMessageData(DBusMessage *message)
57 : TypedMessageData<DBusMessage *>(message) {
58 GetSymbols()->dbus_message_ref()(data());
59 }
60
61 DBusSigMessageData::~DBusSigMessageData() {
62 GetSymbols()->dbus_message_unref()(data());
63 }
64
65 // Implementation of class DBusSigFilter
66
67 // Builds a DBus filter string from given DBus path, interface and member.
68 std::string DBusSigFilter::BuildFilterString(const std::string &path,
69 const std::string &interface,
70 const std::string &member) {
71 std::string ret(DBUS_TYPE "='" DBUS_SIGNAL "'");
72 if (!path.empty()) {
73 ret += ("," DBUS_PATH "='");
74 ret += path;
75 ret += "'";
76 }
77 if (!interface.empty()) {
78 ret += ("," DBUS_INTERFACE "='");
79 ret += interface;
80 ret += "'";
81 }
82 if (!member.empty()) {
83 ret += ("," DBUS_MEMBER "='");
84 ret += member;
85 ret += "'";
86 }
87 return ret;
88 }
89
90 // Forwards the message to the given instance.
91 DBusHandlerResult DBusSigFilter::DBusCallback(DBusConnection *dbus_conn,
92 DBusMessage *message,
93 void *instance) {
94 ASSERT(instance);
95 if (instance) {
96 return static_cast<DBusSigFilter *>(instance)->Callback(message);
97 }
98 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
99 }
100
101 // Posts a message to caller thread.
102 DBusHandlerResult DBusSigFilter::Callback(DBusMessage *message) {
103 if (caller_thread_) {
104 caller_thread_->Post(RTC_FROM_HERE, this, DSM_SIGNAL,
105 new DBusSigMessageData(message));
106 }
107 // Don't "eat" the message here. Let it pop up.
108 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
109 }
110
111 // From MessageHandler.
112 void DBusSigFilter::OnMessage(Message *message) {
113 if (message != NULL && DSM_SIGNAL == message->message_id) {
114 DBusSigMessageData *msg =
115 static_cast<DBusSigMessageData *>(message->pdata);
116 if (msg) {
117 ProcessSignal(msg->data());
118 delete msg;
119 }
120 }
121 }
122
123 // Definition of private class DBusMonitoringThread.
124 // It creates a worker-thread to listen signals on DBus. The worker-thread will
125 // be running in a priate GMainLoop forever until either Stop() has been invoked
126 // or it hits an error.
127 class DBusMonitor::DBusMonitoringThread : public rtc::Thread {
128 public:
129 explicit DBusMonitoringThread(DBusMonitor *monitor,
130 GMainContext *context,
131 GMainLoop *mainloop,
132 std::vector<DBusSigFilter *> *filter_list)
133 : monitor_(monitor),
134 context_(context),
135 mainloop_(mainloop),
136 connection_(NULL),
137 idle_source_(NULL),
138 filter_list_(filter_list) {
139 ASSERT(monitor_);
140 ASSERT(context_);
141 ASSERT(mainloop_);
142 ASSERT(filter_list_);
143 }
144
145 virtual ~DBusMonitoringThread() {
146 Stop();
147 }
148
149 // Override virtual method of Thread. Context: worker-thread.
150 virtual void Run() {
151 ASSERT(NULL == connection_);
152
153 // Setup DBus connection and start monitoring.
154 monitor_->OnMonitoringStatusChanged(DMS_INITIALIZING);
155 if (!Setup()) {
156 LOG(LS_ERROR) << "DBus monitoring setup failed.";
157 monitor_->OnMonitoringStatusChanged(DMS_FAILED);
158 CleanUp();
159 return;
160 }
161 monitor_->OnMonitoringStatusChanged(DMS_RUNNING);
162 g_main_loop_run(mainloop_);
163 monitor_->OnMonitoringStatusChanged(DMS_STOPPED);
164
165 // Done normally. Clean up DBus connection.
166 CleanUp();
167 return;
168 }
169
170 // Override virtual method of Thread. Context: caller-thread.
171 virtual void Stop() {
172 ASSERT(NULL == idle_source_);
173 // Add an idle source and let the gmainloop quit on idle.
174 idle_source_ = g_idle_source_new();
175 if (idle_source_) {
176 g_source_set_callback(idle_source_, &Idle, this, NULL);
177 g_source_attach(idle_source_, context_);
178 } else {
179 LOG(LS_ERROR) << "g_idle_source_new() failed.";
180 QuitGMainloop(); // Try to quit anyway.
181 }
182
183 Thread::Stop(); // Wait for the thread.
184 }
185
186 private:
187 // Registers all DBus filters.
188 void RegisterAllFilters() {
189 ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()(
190 connection_));
191
192 for (std::vector<DBusSigFilter *>::iterator it = filter_list_->begin();
193 it != filter_list_->end(); ++it) {
194 DBusSigFilter *filter = (*it);
195 if (!filter) {
196 LOG(LS_ERROR) << "DBusSigFilter list corrupted.";
197 continue;
198 }
199
200 GetSymbols()->dbus_bus_add_match()(
201 GetSymbols()->dbus_g_connection_get_connection()(connection_),
202 filter->filter().c_str(), NULL);
203
204 if (!GetSymbols()->dbus_connection_add_filter()(
205 GetSymbols()->dbus_g_connection_get_connection()(connection_),
206 &DBusSigFilter::DBusCallback, filter, NULL)) {
207 LOG(LS_ERROR) << "dbus_connection_add_filter() failed."
208 << "Filter: " << filter->filter();
209 continue;
210 }
211 }
212 }
213
214 // Unregisters all DBus filters.
215 void UnRegisterAllFilters() {
216 ASSERT(NULL != GetSymbols()->dbus_g_connection_get_connection()(
217 connection_));
218
219 for (std::vector<DBusSigFilter *>::iterator it = filter_list_->begin();
220 it != filter_list_->end(); ++it) {
221 DBusSigFilter *filter = (*it);
222 if (!filter) {
223 LOG(LS_ERROR) << "DBusSigFilter list corrupted.";
224 continue;
225 }
226 GetSymbols()->dbus_connection_remove_filter()(
227 GetSymbols()->dbus_g_connection_get_connection()(connection_),
228 &DBusSigFilter::DBusCallback, filter);
229 }
230 }
231
232 // Sets up the monitoring thread.
233 bool Setup() {
234 g_main_context_push_thread_default(context_);
235
236 // Start connection to dbus.
237 // If dbus daemon is not running, returns false immediately.
238 connection_ = GetSymbols()->dbus_g_bus_get_private()(monitor_->type_,
239 context_, NULL);
240 if (NULL == connection_) {
241 LOG(LS_ERROR) << "dbus_g_bus_get_private() unable to get connection.";
242 return false;
243 }
244 if (NULL == GetSymbols()->dbus_g_connection_get_connection()(connection_)) {
245 LOG(LS_ERROR) << "dbus_g_connection_get_connection() returns NULL. "
246 << "DBus daemon is probably not running.";
247 return false;
248 }
249
250 // Application don't exit if DBus daemon die.
251 GetSymbols()->dbus_connection_set_exit_on_disconnect()(
252 GetSymbols()->dbus_g_connection_get_connection()(connection_), FALSE);
253
254 // Connect all filters.
255 RegisterAllFilters();
256
257 return true;
258 }
259
260 // Cleans up the monitoring thread.
261 void CleanUp() {
262 if (idle_source_) {
263 // We did an attach() with the GSource, so we need to destroy() it.
264 g_source_destroy(idle_source_);
265 // We need to unref() the GSource to end the last reference we got.
266 g_source_unref(idle_source_);
267 idle_source_ = NULL;
268 }
269 if (connection_) {
270 if (GetSymbols()->dbus_g_connection_get_connection()(connection_)) {
271 UnRegisterAllFilters();
272 GetSymbols()->dbus_connection_close()(
273 GetSymbols()->dbus_g_connection_get_connection()(connection_));
274 }
275 GetSymbols()->dbus_g_connection_unref()(connection_);
276 connection_ = NULL;
277 }
278 g_main_loop_unref(mainloop_);
279 mainloop_ = NULL;
280 g_main_context_unref(context_);
281 context_ = NULL;
282 }
283
284 // Handles callback on Idle. We only add this source when ready to stop.
285 static gboolean Idle(gpointer data) {
286 static_cast<DBusMonitoringThread *>(data)->QuitGMainloop();
287 return TRUE;
288 }
289
290 // We only hit this when ready to quit.
291 void QuitGMainloop() {
292 g_main_loop_quit(mainloop_);
293 }
294
295 DBusMonitor *monitor_;
296
297 GMainContext *context_;
298 GMainLoop *mainloop_;
299 DBusGConnection *connection_;
300 GSource *idle_source_;
301
302 std::vector<DBusSigFilter *> *filter_list_;
303 };
304
305 // Implementation of class DBusMonitor
306
307 // Returns DBus-Glib symbol handle. Initialize it first if hasn't.
308 LibDBusGlibSymbolTable *DBusMonitor::GetDBusGlibSymbolTable() {
309 // This is multi-thread safe.
310 pthread_once(&g_dbus_init_once, InitializeDBusGlibSymbol);
311
312 return g_dbus_symbol;
313 };
314
315 // Creates an instance of DBusMonitor
316 DBusMonitor *DBusMonitor::Create(DBusBusType type) {
317 if (NULL == DBusMonitor::GetDBusGlibSymbolTable()) {
318 return NULL;
319 }
320 return new DBusMonitor(type);
321 }
322
323 DBusMonitor::DBusMonitor(DBusBusType type)
324 : type_(type),
325 status_(DMS_NOT_INITIALIZED),
326 monitoring_thread_(NULL) {
327 ASSERT(type_ == DBUS_BUS_SYSTEM || type_ == DBUS_BUS_SESSION);
328 }
329
330 DBusMonitor::~DBusMonitor() {
331 StopMonitoring();
332 }
333
334 bool DBusMonitor::AddFilter(DBusSigFilter *filter) {
335 if (monitoring_thread_) {
336 return false;
337 }
338 if (!filter) {
339 return false;
340 }
341 filter_list_.push_back(filter);
342 return true;
343 }
344
345 bool DBusMonitor::StartMonitoring() {
346 if (!monitoring_thread_) {
347 g_type_init();
348 // g_thread_init API is deprecated since glib 2.31.0, see release note:
349 // http://mail.gnome.org/archives/gnome-announce-list/2011-October/msg00041. html
350 #if !GLIB_CHECK_VERSION(2, 31, 0)
351 g_thread_init(NULL);
352 #endif
353 GetSymbols()->dbus_g_thread_init()();
354
355 GMainContext *context = g_main_context_new();
356 if (NULL == context) {
357 LOG(LS_ERROR) << "g_main_context_new() failed.";
358 return false;
359 }
360
361 GMainLoop *mainloop = g_main_loop_new(context, FALSE);
362 if (NULL == mainloop) {
363 LOG(LS_ERROR) << "g_main_loop_new() failed.";
364 g_main_context_unref(context);
365 return false;
366 }
367
368 monitoring_thread_ = new DBusMonitoringThread(this, context, mainloop,
369 &filter_list_);
370 if (monitoring_thread_ == NULL) {
371 LOG(LS_ERROR) << "Failed to create DBus monitoring thread.";
372 g_main_context_unref(context);
373 g_main_loop_unref(mainloop);
374 return false;
375 }
376 monitoring_thread_->Start();
377 }
378 return true;
379 }
380
381 bool DBusMonitor::StopMonitoring() {
382 if (monitoring_thread_) {
383 monitoring_thread_->Stop();
384 monitoring_thread_ = NULL;
385 }
386 return true;
387 }
388
389 DBusMonitor::DBusMonitorStatus DBusMonitor::GetStatus() {
390 return status_;
391 }
392
393 void DBusMonitor::OnMonitoringStatusChanged(DBusMonitorStatus status) {
394 status_ = status;
395 }
396
397 #undef LATE
398
399 } // namespace rtc
400
401 #endif // HAVE_DBUS_GLIB
OLDNEW
« no previous file with comments | « webrtc/base/dbus.h ('k') | webrtc/base/dbus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698