Line data Source code
1 : /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "DBusWatcher.h"
8 : #include "mozilla/Unused.h"
9 : #include "nsThreadUtils.h"
10 :
11 : namespace mozilla {
12 : namespace ipc {
13 :
14 0 : DBusWatcher::DBusWatcher(DBusConnection* aConnection, DBusWatch* aWatch)
15 : : mConnection(aConnection)
16 0 : , mWatch(aWatch)
17 : {
18 0 : MOZ_ASSERT(mConnection);
19 0 : MOZ_ASSERT(mWatch);
20 0 : }
21 :
22 0 : DBusWatcher::~DBusWatcher()
23 0 : { }
24 :
25 : DBusConnection*
26 0 : DBusWatcher::GetConnection()
27 : {
28 0 : return mConnection;
29 : }
30 :
31 : void
32 0 : DBusWatcher::StartWatching()
33 : {
34 0 : MOZ_ASSERT(!NS_IsMainThread());
35 :
36 0 : auto flags = dbus_watch_get_flags(mWatch);
37 :
38 0 : if (!(flags & (DBUS_WATCH_READABLE|DBUS_WATCH_WRITABLE))) {
39 0 : return;
40 : }
41 :
42 0 : auto ioLoop = MessageLoopForIO::current();
43 :
44 0 : auto fd = dbus_watch_get_unix_fd(mWatch);
45 :
46 0 : if (flags & DBUS_WATCH_READABLE) {
47 0 : ioLoop->WatchFileDescriptor(fd, true, MessageLoopForIO::WATCH_READ,
48 0 : &mReadWatcher, this);
49 : }
50 0 : if (flags & DBUS_WATCH_WRITABLE) {
51 0 : ioLoop->WatchFileDescriptor(fd, true, MessageLoopForIO::WATCH_WRITE,
52 0 : &mWriteWatcher, this);
53 : }
54 : }
55 :
56 : void
57 0 : DBusWatcher::StopWatching()
58 : {
59 0 : MOZ_ASSERT(!NS_IsMainThread());
60 :
61 0 : auto flags = dbus_watch_get_flags(mWatch);
62 :
63 0 : if (flags & DBUS_WATCH_READABLE) {
64 0 : mReadWatcher.StopWatchingFileDescriptor();
65 : }
66 0 : if (flags & DBUS_WATCH_WRITABLE) {
67 0 : mWriteWatcher.StopWatchingFileDescriptor();
68 : }
69 0 : }
70 :
71 : // DBus utility functions, used as function pointers in DBus setup
72 :
73 : void
74 0 : DBusWatcher::FreeFunction(void* aData)
75 : {
76 0 : UniquePtr<DBusWatcher> watcher(static_cast<DBusWatcher*>(aData));
77 0 : }
78 :
79 : dbus_bool_t
80 0 : DBusWatcher::AddWatchFunction(DBusWatch* aWatch, void* aData)
81 : {
82 0 : MOZ_ASSERT(!NS_IsMainThread());
83 :
84 0 : auto connection = static_cast<DBusConnection*>(aData);
85 :
86 : UniquePtr<DBusWatcher> dbusWatcher =
87 0 : MakeUnique<DBusWatcher>(connection, aWatch);
88 :
89 0 : dbus_watch_set_data(aWatch, dbusWatcher.get(), DBusWatcher::FreeFunction);
90 :
91 0 : if (dbus_watch_get_enabled(aWatch)) {
92 0 : dbusWatcher->StartWatching();
93 : }
94 :
95 0 : Unused << dbusWatcher.release(); // picked up in |FreeFunction|
96 :
97 0 : return TRUE;
98 : }
99 :
100 : void
101 0 : DBusWatcher::RemoveWatchFunction(DBusWatch* aWatch, void* aData)
102 : {
103 0 : MOZ_ASSERT(!NS_IsMainThread());
104 :
105 0 : auto dbusWatcher = static_cast<DBusWatcher*>(dbus_watch_get_data(aWatch));
106 :
107 0 : dbusWatcher->StopWatching();
108 0 : }
109 :
110 : void
111 0 : DBusWatcher::ToggleWatchFunction(DBusWatch* aWatch, void* aData)
112 : {
113 0 : MOZ_ASSERT(!NS_IsMainThread());
114 :
115 0 : auto dbusWatcher = static_cast<DBusWatcher*>(dbus_watch_get_data(aWatch));
116 :
117 0 : if (dbus_watch_get_enabled(aWatch)) {
118 0 : dbusWatcher->StartWatching();
119 : } else {
120 0 : dbusWatcher->StopWatching();
121 : }
122 0 : }
123 :
124 : // I/O-loop callbacks
125 :
126 : void
127 0 : DBusWatcher::OnFileCanReadWithoutBlocking(int aFd)
128 : {
129 0 : MOZ_ASSERT(!NS_IsMainThread());
130 :
131 0 : dbus_watch_handle(mWatch, DBUS_WATCH_READABLE);
132 :
133 : DBusDispatchStatus dbusDispatchStatus;
134 :
135 0 : do {
136 0 : dbusDispatchStatus = dbus_connection_dispatch(mConnection);
137 0 : } while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS);
138 0 : }
139 :
140 : void
141 0 : DBusWatcher::OnFileCanWriteWithoutBlocking(int aFd)
142 : {
143 0 : MOZ_ASSERT(!NS_IsMainThread());
144 :
145 0 : dbus_watch_handle(mWatch, DBUS_WATCH_WRITABLE);
146 0 : }
147 :
148 : } // namespace ipc
149 : } // namespace mozilla
|