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

Side by Side Diff: dbus/bus.h

Issue 7491029: Implement Bus and ObjectProxy classes for our D-Bus library. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: another clang challenge Created 9 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | dbus/bus.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 (c) 2011 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #ifndef DBUS_BUS_H_
7 #define DBUS_BUS_H_
8 #pragma once
9
10 #include <set>
11 #include <string>
12 #include <dbus/dbus.h>
13
14 #include "base/callback.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/tracked_objects.h"
18
19 class MessageLoop;
20
21 namespace base {
22 class Thread;
23 }
24
25 namespace dbus {
26
27 class ExportedObject;
28 class ObjectProxy;
29
30 // Bus is used to establish a connection with D-Bus, create object
31 // proxies, and export objects.
32 //
33 // For asynchronous operations such as an asynchronous method call, the
34 // bus object will use a message loop to monitor the underlying file
35 // descriptor used for D-Bus communication. By default, the bus will use
36 // the current thread's MessageLoopForIO. If |dbus_thread| option is
37 // specified, the bus will use the D-Bus thread's message loop.
38 //
39 // THREADING
40 //
41 // In the D-Bus library, we use the two threads:
42 //
43 // - The origin thread: the thread that created the Bus object.
44 // - The D-Bus thread: the thread supplifed by |dbus_thread| option.
45 //
46 // The origin thread is usually Chrome's UI thread. The D-Bus thread is
47 // usually a dedicated thread for the D-Bus library.
48 //
49 // BLOCKING CALLS
50 //
51 // Functions that issue blocking calls are marked "BLOCKING CALL" and
52 // these functions should be called in the D-Bus thread (if
53 // supplied). AssertOnDBusThread() is placed in these functions.
54 //
55 // Note that it's hard to tell if a libdbus function is actually blocking
56 // or not (ex. dbus_bus_request_name() internally calls
57 // dbus_connection_send_with_reply_and_block(), which is a blocking
58 // call). To err on the side, we consider all libdbus functions that deal
59 // with the connection to dbus-damoen to be blocking.
60 //
61 // EXAMPLE USAGE:
62 //
63 // Synchronous method call:
64 //
65 // dbus::Bus::Options options;
66 // // Set up the bus options here.
67 // ...
68 // dbus::Bus bus(options);
69 //
70 // dbus::ObjectProxy* object_proxy =
71 // bus.GetObjectProxy(service_name, object_path);
72 //
73 // dbus::MethodCall method_call(interface_name, method_name);
74 // dbus::Response response;
75 // bool success =
76 // object_proxy.CallMethodAndBlock(&method_call, timeout_ms, &response);
77 //
78 // Asynchronous method call:
79 //
80 // void OnResponse(dbus::Response* response) {
81 // // response is NULL if the method call failed.
82 // if (!response)
83 // return;
84 // }
85 //
86 // ...
87 // object_proxy.CallMethod(&method_call, timeout_ms,
88 // base::Bind(&OnResponse));
89 //
90 // Exporting a method:
91 //
92 // Response* Echo(dbus::MethodCall* method_call) {
93 // // Do something with method_call.
94 // Response* response = Response::FromMethodCall(method_call);
95 // // Build response here.
96 // return response;
97 // }
98 //
99 // void OnExported(const std::string& interface_name,
100 // const std::string& object_path,
101 // bool success) {
102 // // success is true if the method was exported successfully.
103 // }
104 //
105 // ...
106 // dbus::ExportedObject* exported_object =
107 // bus.GetExportedObject(service_name, object_path);
108 // exported_object.ExportMethod(interface_name, method_name,
109 // base::Bind(&Echo),
110 // base::Bind(&OnExported));
111 //
112 // WHY IS THIS A REF COUNTED OBJECT?
113 //
114 // Bus is a ref counted object, to ensure that |this| of the object is
115 // alive when callbacks referencing |this| are called. However, after
116 // Shutdown() is called, |connection_| can be NULL. Hence, calbacks should
117 // not rely on that |connection_| is alive.
118 class Bus : public base::RefCountedThreadSafe<Bus> {
119 public:
120 // Specifies the bus type. SESSION is used to communicate with per-user
121 // services like GNOME applications. SYSTEM is used to communicate with
122 // system-wide services like NetworkManager.
123 enum BusType {
124 SESSION = DBUS_BUS_SESSION,
125 SYSTEM = DBUS_BUS_SYSTEM,
126 };
127
128 // Specifies the connection type. PRIVATE should usually be used unless
129 // you are sure that SHARED is safe for you, which is unlikely the case
130 // in Chrome.
131 //
132 // PRIVATE gives you a private connection, that won't be shared with
133 // other Bus objects.
134 //
135 // SHARED gives you a connection shared among other Bus objects, which
136 // is unsafe if the connection is shared with multiple threads.
137 enum ConnectionType {
138 PRIVATE,
139 SHARED,
140 };
141
142 // Options used to create a Bus object.
143 struct Options {
144 Options();
145 ~Options();
146
147 BusType bus_type; // SESSION by default.
148 ConnectionType connection_type; // PRIVATE by default.
149 // If the thread is set, the bus object will use the message loop
150 // attached to the thread to process asynchronous operations.
151 //
152 // The thread should meet the following requirements:
153 // 1) Already running.
154 // 2) Has a MessageLoopForIO.
155 // 3) Outlives the bus.
156 base::Thread* dbus_thread; // NULL by default.
157 };
158
159 // Called when shutdown is done. Used for Shutdown().
160 typedef base::Callback<void ()> OnShutdownCallback;
161
162 // Creates a Bus object. The actual connection will be established when
163 // Connect() is called.
164 explicit Bus(const Options& options);
165
166 // Gets the object proxy for the given service name and the object path.
167 // The caller must not delete the returned object. The bus will own the
168 // object. Never returns NULL.
169 //
170 // The object proxy is used to call remote methods.
171 //
172 // |service_name| looks like "org.freedesktop.NetworkManager", and
173 // |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0".
174 //
175 // Must be called in the origin thread.
176 virtual ObjectProxy* GetObjectProxy(const std::string& service_name,
177 const std::string& object_path);
178
179 // Gets the exported object for the given service name and the object
180 // path. The caller must not delete the returned object. The bus will
181 // own the object. Never returns NULL.
182 //
183 // The exported object is used to export objects to other D-Bus clients.
184 //
185 // Must be called in the origin thread.
186 virtual ExportedObject* GetExportedObject(const std::string& service_name,
187 const std::string& object_path);
188
189 // Shuts down the bus and blocks until it's done. More specifically, this
190 // function does the following:
191 //
192 // - Unregisters the object paths
193 // - Releases the service names
194 // - Closes the connection to dbus-daemon.
195 //
196 // BLOCKING CALL.
197 virtual void ShutdownAndBlock();
198
199 // Shuts down the bus in the D-Bus thread. |callback| will be called in
200 // the origin thread.
201 //
202 // Must be called in the origin thread.
203 virtual void Shutdown(OnShutdownCallback callback);
204
205 //
206 // The public functions below are not intended to be used in client
207 // code. These are used to implement ObjectProxy and ExportedObject.
208 //
209
210 // Connects the bus to the dbus-daemon.
211 // Returns true on success, or the bus is already connected.
212 //
213 // BLOCKING CALL.
214 virtual bool Connect();
215
216 // Requests the ownership of the given service name.
217 // Returns true on success, or the the service name is already obtained.
218 //
219 // BLOCKING CALL.
220 virtual bool RequestOwnership(const std::string& service_name);
221
222 // Releases the ownership of the given service name.
223 // Returns true on success.
224 //
225 // BLOCKING CALL.
226 virtual bool ReleaseOwnership(const std::string& service_name);
227
228 // Sets up async operations.
229 // Returns true on success, or it's already set up.
230 // This function needs to be called before starting async operations.
231 //
232 // BLOCKING CALL.
233 virtual bool SetUpAsyncOperations();
234
235 // Sends a message to the bus and blocks until the response is
236 // received. Used to implement synchronous method calls.
237 //
238 // BLOCKING CALL.
239 virtual DBusMessage* SendWithReplyAndBlock(DBusMessage* request,
240 int timeout_ms,
241 DBusError* error);
242
243 // Requests to send a message to the bus.
244 //
245 // BLOCKING CALL.
246 virtual void SendWithReply(DBusMessage* request,
247 DBusPendingCall** pending_call,
248 int timeout_ms);
249
250 // Tries to register the object path.
251 //
252 // BLOCKING CALL.
253 virtual bool TryRegisterObjectPath(const std::string& object_path,
254 const DBusObjectPathVTable* vtable,
255 void* user_data,
256 DBusError* error);
257
258 // Unregister the object path.
259 //
260 // BLOCKING CALL.
261 virtual void UnregisterObjectPath(const std::string& object_path);
262
263 // Posts the task to the message loop of the thread that created the bus.
264 virtual void PostTaskToOriginThread(
265 const tracked_objects::Location& from_here,
266 const base::Closure& task);
267
268 // Posts the task to the message loop of the D-Bus thread. If D-Bus
269 // thread is not supplied, the message loop of the origin thread will be
270 // used.
271 virtual void PostTaskToDBusThread(
272 const tracked_objects::Location& from_here,
273 const base::Closure& task);
274
275 // Posts the delayed task to the message loop of the D-Bus thread. If
276 // D-Bus thread is not supplied, the message loop of the origin thread
277 // will be used.
278 virtual void PostDelayedTaskToDBusThread(
279 const tracked_objects::Location& from_here,
280 const base::Closure& task,
281 int delay_ms);
282
283 // Returns true if the bus has the D-Bus thread.
284 virtual bool HasDBusThread();
285
286 // Check whether the current thread is on the origin thread (the thread
287 // that created the bus). If not, DCHECK will fail.
288 virtual void AssertOnOriginThread();
289
290 // Check whether the current thread is on the D-Bus thread. If not,
291 // DCHECK will fail. If the D-Bus thread is not supplied, it calls
292 // AssertOnOriginThread().
293 virtual void AssertOnDBusThread();
294
295 private:
296 friend class base::RefCountedThreadSafe<Bus>;
297 virtual ~Bus();
298
299 // Helper function used for Shutdown().
300 void ShutdownInternal(OnShutdownCallback callback);
301
302 // Processes the all incoming data to the connection, if any.
303 //
304 // BLOCKING CALL.
305 void ProcessAllIncomingDataIfAny();
306
307 // Called when a watch object is added. Used to start monitoring the
308 // file descriptor used for D-Bus communication.
309 dbus_bool_t OnAddWatch(DBusWatch* raw_watch);
310
311 // Called when a watch object is removed.
312 void OnRemoveWatch(DBusWatch* raw_watch);
313
314 // Called when the "enabled" status of |raw_watch| is toggled.
315 void OnToggleWatch(DBusWatch* raw_watch);
316
317 // Called when a timeout object is added. Used to start monitoring
318 // timeout for method calls.
319 dbus_bool_t OnAddTimeout(DBusTimeout* raw_timeout);
320
321 // Called when a timeout object is removed.
322 void OnRemoveTimeout(DBusTimeout* raw_timeout);
323
324 // Called when the "enabled" status of |raw_timeout| is toggled.
325 void OnToggleTimeout(DBusTimeout* raw_timeout);
326
327 // Called when the dispatch status (i.e. if any incoming data is
328 // available) is changed.
329 void OnDispatchStatusChanged(DBusConnection* connection,
330 DBusDispatchStatus status);
331
332 // Callback helper functions. Redirects to the corresponding member function.
333 static dbus_bool_t OnAddWatchThunk(DBusWatch* raw_watch, void* data);
334 static void OnRemoveWatchThunk(DBusWatch* raw_watch, void* data);
335 static void OnToggleWatchThunk(DBusWatch* raw_watch, void* data);
336 static dbus_bool_t OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data);
337 static void OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data);
338 static void OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data);
339 static void OnDispatchStatusChangedThunk(DBusConnection* connection,
340 DBusDispatchStatus status,
341 void* data);
342 const BusType bus_type_;
343 const ConnectionType connection_type_;
344 base::Thread* dbus_thread_;
345 DBusConnection* connection_;
346
347 MessageLoop* origin_loop_;
348 base::PlatformThreadId origin_thread_id_;
349 base::PlatformThreadId dbus_thread_id_;
350
351 std::set<std::string> owned_service_names_;
352 std::vector<scoped_refptr<dbus::ObjectProxy> > object_proxies_;
353 std::vector<scoped_refptr<dbus::ExportedObject> > exported_objects_;
354
355 bool async_operations_are_set_up_;
356
357 // Counters to make sure that OnAddWatch()/OnRemoveWatch() and
358 // OnAddTimeout()/OnRemoveTimeou() are balanced.
359 int num_pending_watches_;
360 int num_pending_timeouts_;
361
362 DISALLOW_COPY_AND_ASSIGN(Bus);
363 };
364
365 } // namespace dbus
366
367 #endif // DBUS_BUS_H_
OLDNEW
« no previous file with comments | « no previous file | dbus/bus.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698