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

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

Powered by Google App Engine
This is Rietveld 408576698