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

Side by Side Diff: athena/system/device_socket_listener.cc

Issue 490033003: Fixes three crashes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add file thread Created 6 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 | « athena/system/device_socket_listener.h ('k') | athena/system/orientation_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "athena/system/device_socket_listener.h" 5 #include "athena/system/device_socket_listener.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <map> 8 #include <map>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/memory/singleton.h"
16 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
17 #include "base/observer_list.h" 16 #include "base/observer_list.h"
18 #include "base/stl_util.h" 17 #include "base/stl_util.h"
19 #include "ipc/unix_domain_socket_util.h" 18 #include "ipc/unix_domain_socket_util.h"
20 19
21 namespace athena { 20 namespace athena {
22 21
23 namespace { 22 namespace {
24 23
25 typedef ObserverList<DeviceSocketListener> DeviceSocketListeners; 24 typedef ObserverList<DeviceSocketListener> DeviceSocketListeners;
(...skipping 22 matching lines...) Expand all
48 47
49 DISALLOW_COPY_AND_ASSIGN(DeviceSocketReader); 48 DISALLOW_COPY_AND_ASSIGN(DeviceSocketReader);
50 }; 49 };
51 50
52 class DeviceSocketManager; 51 class DeviceSocketManager;
53 DeviceSocketManager* device_socket_manager_instance_ = NULL; 52 DeviceSocketManager* device_socket_manager_instance_ = NULL;
54 53
55 // A singleton instance for managing all connections to sockets. 54 // A singleton instance for managing all connections to sockets.
56 class DeviceSocketManager { 55 class DeviceSocketManager {
57 public: 56 public:
58 static void Create(scoped_refptr<base::TaskRunner> io_task_runner) { 57 static void Create(scoped_refptr<base::TaskRunner> file_task_runner) {
59 device_socket_manager_instance_ = 58 device_socket_manager_instance_ = new DeviceSocketManager(file_task_runner);
60 new DeviceSocketManager(io_task_runner);
61 } 59 }
62 60
63 static void Shutdown() { 61 static void Shutdown() {
64 CHECK(device_socket_manager_instance_); 62 CHECK(device_socket_manager_instance_);
65 delete device_socket_manager_instance_; 63 device_socket_manager_instance_->ScheduleDelete();
64 // Once scheduled to be deleted, no-one should be
65 // able to access it.
66 device_socket_manager_instance_ = NULL; 66 device_socket_manager_instance_ = NULL;
67 } 67 }
68 68
69 static DeviceSocketManager* GetInstanceUnsafe() {
70 return device_socket_manager_instance_;
71 }
72
69 static DeviceSocketManager* GetInstance() { 73 static DeviceSocketManager* GetInstance() {
70 CHECK(device_socket_manager_instance_); 74 CHECK(device_socket_manager_instance_);
71 return device_socket_manager_instance_; 75 return device_socket_manager_instance_;
72 } 76 }
73 77
74 // If there isn't an existing connection to |socket_path|, then opens a 78 // If there isn't an existing connection to |socket_path|, then opens a
75 // connection to |socket_path| and starts listening for data. All listeners 79 // connection to |socket_path| and starts listening for data. All listeners
76 // for |socket_path| receives data when data is available on the socket. 80 // for |socket_path| receives data when data is available on the socket.
77 void StartListening(const std::string& socket_path, 81 void StartListening(const std::string& socket_path,
78 size_t data_size, 82 size_t data_size,
79 DeviceSocketListener* listener); 83 DeviceSocketListener* listener);
80 84
81 // Removes |listener| from the list of listeners that receive data from 85 // Removes |listener| from the list of listeners that receive data from
82 // |socket_path|. If this is the last listener, then this closes the 86 // |socket_path|. If this is the last listener, then this closes the
83 // connection to the socket. 87 // connection to the socket.
84 void StopListening(const std::string& socket_path, 88 void StopListening(const std::string& socket_path,
85 DeviceSocketListener* listener); 89 DeviceSocketListener* listener);
86 90
87 // Sends data to all the listeners registered to receive data from 91 // Sends data to all the listeners registered to receive data from
88 // |socket_path|. 92 // |socket_path|.
89 void OnDataAvailable(const std::string& socket_path, 93 void OnDataAvailable(const std::string& socket_path,
90 const void* data); 94 const void* data);
91 95
92 // Notifies listeners of errors reading from the socket and closes it. 96 // Notifies listeners of errors reading from the socket and closes it.
93 void OnError(const std::string& socket_path, int err); 97 void OnError(const std::string& socket_path, int err);
94 void OnEOF(const std::string& socket_path); 98 void OnEOF(const std::string& socket_path);
95 99
96 private: 100 private:
97 friend struct DefaultSingletonTraits<DeviceSocketManager>;
98
99 struct SocketData { 101 struct SocketData {
100 SocketData() 102 SocketData()
101 : fd(-1) { 103 : fd(-1) {
102 } 104 }
103 105
104 int fd; 106 int fd;
105 DeviceSocketListeners observers; 107 DeviceSocketListeners observers;
106 scoped_ptr<base::MessagePumpLibevent::FileDescriptorWatcher> controller; 108 scoped_ptr<base::MessagePumpLibevent::FileDescriptorWatcher> controller;
107 scoped_ptr<DeviceSocketReader> watcher; 109 scoped_ptr<DeviceSocketReader> watcher;
108 }; 110 };
109 111
110 DeviceSocketManager(scoped_refptr<base::TaskRunner> io_task_runner) 112 static void DeleteOnFILE(DeviceSocketManager* manager) { delete manager; }
111 : io_task_runner_(io_task_runner) { 113
112 } 114 DeviceSocketManager(scoped_refptr<base::TaskRunner> file_task_runner)
115 : file_task_runner_(file_task_runner) {}
113 116
114 ~DeviceSocketManager() { 117 ~DeviceSocketManager() {
115 STLDeleteContainerPairSecondPointers(socket_data_.begin(), 118 STLDeleteContainerPairSecondPointers(socket_data_.begin(),
116 socket_data_.end()); 119 socket_data_.end());
117 } 120 }
118 121
119 void StartListeningOnIO(const std::string& socket_path, 122 void ScheduleDelete();
120 size_t data_size,
121 DeviceSocketListener* listener);
122 123
123 void StopListeningOnIO(const std::string& socket_path, 124 void StartListeningOnFILE(const std::string& socket_path,
124 DeviceSocketListener* listener); 125 size_t data_size,
126 DeviceSocketListener* listener);
127
128 void StopListeningOnFILE(const std::string& socket_path,
129 DeviceSocketListener* listener);
125 130
126 void CloseSocket(const std::string& socket_path); 131 void CloseSocket(const std::string& socket_path);
127 132
128 std::map<std::string, SocketData*> socket_data_; 133 std::map<std::string, SocketData*> socket_data_;
129 scoped_refptr<base::TaskRunner> io_task_runner_; 134 scoped_refptr<base::TaskRunner> file_task_runner_;
130 135
131 DISALLOW_COPY_AND_ASSIGN(DeviceSocketManager); 136 DISALLOW_COPY_AND_ASSIGN(DeviceSocketManager);
132 }; 137 };
133 138
134 //////////////////////////////////////////////////////////////////////////////// 139 ////////////////////////////////////////////////////////////////////////////////
135 // DeviceSocketReader 140 // DeviceSocketReader
136 141
137 void DeviceSocketReader::OnFileCanReadWithoutBlocking(int fd) { 142 void DeviceSocketReader::OnFileCanReadWithoutBlocking(int fd) {
138 ssize_t read_size = recv(fd, data_.get(), data_size_, 0); 143 ssize_t read_size = recv(fd, data_.get(), data_size_, 0);
139 if (read_size < 0) { 144 if (read_size < 0) {
(...skipping 15 matching lines...) Expand all
155 void DeviceSocketReader::OnFileCanWriteWithoutBlocking(int fd) { 160 void DeviceSocketReader::OnFileCanWriteWithoutBlocking(int fd) {
156 NOTREACHED(); 161 NOTREACHED();
157 } 162 }
158 163
159 //////////////////////////////////////////////////////////////////////////////// 164 ////////////////////////////////////////////////////////////////////////////////
160 // DeviceSocketManager 165 // DeviceSocketManager
161 166
162 void DeviceSocketManager::StartListening(const std::string& socket_path, 167 void DeviceSocketManager::StartListening(const std::string& socket_path,
163 size_t data_size, 168 size_t data_size,
164 DeviceSocketListener* listener) { 169 DeviceSocketListener* listener) {
165 io_task_runner_->PostTask(FROM_HERE, 170 file_task_runner_->PostTask(
166 base::Bind(&DeviceSocketManager::StartListeningOnIO, 171 FROM_HERE,
167 base::Unretained(this), socket_path, data_size, listener)); 172 base::Bind(&DeviceSocketManager::StartListeningOnFILE,
173 base::Unretained(this),
174 socket_path,
175 data_size,
176 listener));
168 } 177 }
169 178
170 void DeviceSocketManager::StopListening(const std::string& socket_path, 179 void DeviceSocketManager::StopListening(const std::string& socket_path,
171 DeviceSocketListener* listener) { 180 DeviceSocketListener* listener) {
172 io_task_runner_->PostTask(FROM_HERE, 181 file_task_runner_->PostTask(
173 base::Bind(&DeviceSocketManager::StopListeningOnIO, 182 FROM_HERE,
174 base::Unretained(this), socket_path, listener)); 183 base::Bind(&DeviceSocketManager::StopListeningOnFILE,
184 base::Unretained(this),
185 socket_path,
186 listener));
175 } 187 }
176 188
177 void DeviceSocketManager::OnDataAvailable(const std::string& socket_path, 189 void DeviceSocketManager::OnDataAvailable(const std::string& socket_path,
178 const void* data) { 190 const void* data) {
179 CHECK_GT(socket_data_.count(socket_path), 0UL); 191 CHECK_GT(socket_data_.count(socket_path), 0UL);
180 DeviceSocketListeners& listeners = socket_data_[socket_path]->observers; 192 DeviceSocketListeners& listeners = socket_data_[socket_path]->observers;
181 FOR_EACH_OBSERVER(DeviceSocketListener, listeners, OnDataAvailableOnIO(data)); 193 FOR_EACH_OBSERVER(
194 DeviceSocketListener, listeners, OnDataAvailableOnFILE(data));
182 } 195 }
183 196
184 void DeviceSocketManager::CloseSocket(const std::string& socket_path) { 197 void DeviceSocketManager::CloseSocket(const std::string& socket_path) {
185 if (!socket_data_.count(socket_path)) 198 if (!socket_data_.count(socket_path))
186 return; 199 return;
187 SocketData* socket_data = socket_data_[socket_path]; 200 SocketData* socket_data = socket_data_[socket_path];
188 close(socket_data->fd); 201 close(socket_data->fd);
189 delete socket_data; 202 delete socket_data;
190 socket_data_.erase(socket_path); 203 socket_data_.erase(socket_path);
191 } 204 }
192 205
193 void DeviceSocketManager::OnError(const std::string& socket_path, int err) { 206 void DeviceSocketManager::OnError(const std::string& socket_path, int err) {
194 LOG(ERROR) << "Error reading from socket: " << socket_path << ": " 207 LOG(ERROR) << "Error reading from socket: " << socket_path << ": "
195 << strerror(err); 208 << strerror(err);
196 CloseSocket(socket_path); 209 CloseSocket(socket_path);
197 // TODO(flackr): Notify listeners that the socket was closed unexpectedly. 210 // TODO(flackr): Notify listeners that the socket was closed unexpectedly.
198 } 211 }
199 212
200 void DeviceSocketManager::OnEOF(const std::string& socket_path) { 213 void DeviceSocketManager::OnEOF(const std::string& socket_path) {
201 LOG(ERROR) << "EOF reading from socket: " << socket_path; 214 LOG(ERROR) << "EOF reading from socket: " << socket_path;
202 CloseSocket(socket_path); 215 CloseSocket(socket_path);
203 } 216 }
204 217
205 void DeviceSocketManager::StartListeningOnIO(const std::string& socket_path, 218 void DeviceSocketManager::StartListeningOnFILE(const std::string& socket_path,
206 size_t data_size, 219 size_t data_size,
207 DeviceSocketListener* listener) { 220 DeviceSocketListener* listener) {
208 CHECK(io_task_runner_->RunsTasksOnCurrentThread()); 221 CHECK(file_task_runner_->RunsTasksOnCurrentThread());
209 SocketData* socket_data = NULL; 222 SocketData* socket_data = NULL;
210 if (!socket_data_.count(socket_path)) { 223 if (!socket_data_.count(socket_path)) {
211 int socket_fd = -1; 224 int socket_fd = -1;
212 if (!IPC::CreateClientUnixDomainSocket(base::FilePath(socket_path), 225 if (!IPC::CreateClientUnixDomainSocket(base::FilePath(socket_path),
213 &socket_fd)) { 226 &socket_fd)) {
214 LOG(ERROR) << "Error connecting to socket: " << socket_path; 227 LOG(ERROR) << "Error connecting to socket: " << socket_path;
215 return; 228 return;
216 } 229 }
217 230
218 socket_data = new SocketData; 231 socket_data = new SocketData;
(...skipping 11 matching lines...) Expand all
230 true, 243 true,
231 base::MessageLoopForIO::WATCH_READ, 244 base::MessageLoopForIO::WATCH_READ,
232 socket_data->controller.get(), 245 socket_data->controller.get(),
233 socket_data->watcher.get()); 246 socket_data->watcher.get());
234 } else { 247 } else {
235 socket_data = socket_data_[socket_path]; 248 socket_data = socket_data_[socket_path];
236 } 249 }
237 socket_data->observers.AddObserver(listener); 250 socket_data->observers.AddObserver(listener);
238 } 251 }
239 252
240 void DeviceSocketManager::StopListeningOnIO(const std::string& socket_path, 253 void DeviceSocketManager::StopListeningOnFILE(const std::string& socket_path,
241 DeviceSocketListener* listener) { 254 DeviceSocketListener* listener) {
242 if (!socket_data_.count(socket_path)) 255 if (!socket_data_.count(socket_path))
243 return; // Happens if unable to create a socket. 256 return; // Happens if unable to create a socket.
244 257
245 CHECK(io_task_runner_->RunsTasksOnCurrentThread()); 258 CHECK(file_task_runner_->RunsTasksOnCurrentThread());
246 DeviceSocketListeners& listeners = socket_data_[socket_path]->observers; 259 DeviceSocketListeners& listeners = socket_data_[socket_path]->observers;
247 listeners.RemoveObserver(listener); 260 listeners.RemoveObserver(listener);
248 if (!listeners.might_have_observers()) { 261 if (!listeners.might_have_observers()) {
249 // All listeners for this socket has been removed. Close the socket. 262 // All listeners for this socket has been removed. Close the socket.
250 CloseSocket(socket_path); 263 CloseSocket(socket_path);
251 } 264 }
252 } 265 }
253 266
267 void DeviceSocketManager::ScheduleDelete() {
268 // Schedule a task to delete on FILE thread because
269 // there may be a task scheduled on |file_task_runner_|.
270 file_task_runner_->PostTask(
271 FROM_HERE,
272 base::Bind(&DeleteOnFILE, base::Unretained(this)));
273 }
274
254 } // namespace 275 } // namespace
255 276
256 DeviceSocketListener::DeviceSocketListener(const std::string& socket_path, 277 DeviceSocketListener::DeviceSocketListener(const std::string& socket_path,
257 size_t data_size) 278 size_t data_size)
258 : socket_path_(socket_path), 279 : socket_path_(socket_path),
259 data_size_(data_size) { 280 data_size_(data_size) {
260 } 281 }
261 282
262 DeviceSocketListener::~DeviceSocketListener() { 283 DeviceSocketListener::~DeviceSocketListener() {
263 StopListening(); 284 StopListening();
264 } 285 }
265 286
266 // static 287 // static
267 void DeviceSocketListener::CreateSocketManager( 288 void DeviceSocketListener::CreateSocketManager(
268 scoped_refptr<base::TaskRunner> io_task_runner) { 289 scoped_refptr<base::TaskRunner> file_task_runner) {
269 DeviceSocketManager::Create(io_task_runner); 290 DeviceSocketManager::Create(file_task_runner);
270 } 291 }
271 292
272 // static 293 // static
273 void DeviceSocketListener::ShutdownSocketManager() { 294 void DeviceSocketListener::ShutdownSocketManager() {
274 DeviceSocketManager::Shutdown(); 295 DeviceSocketManager::Shutdown();
275 } 296 }
276 297
277 void DeviceSocketListener::StartListening() { 298 void DeviceSocketListener::StartListening() {
278 DeviceSocketManager::GetInstance()->StartListening(socket_path_, 299 DeviceSocketManager::GetInstance()->StartListening(socket_path_,
279 data_size_, 300 data_size_,
280 this); 301 this);
281 } 302 }
282 303
283 void DeviceSocketListener::StopListening() { 304 void DeviceSocketListener::StopListening() {
284 DeviceSocketManager::GetInstance()->StopListening(socket_path_, this); 305 DeviceSocketManager* instance = DeviceSocketManager::GetInstanceUnsafe();
306 if (instance)
307 instance->StopListening(socket_path_, this);
285 } 308 }
286 309
287 } // namespace athena 310 } // namespace athena
OLDNEW
« no previous file with comments | « athena/system/device_socket_listener.h ('k') | athena/system/orientation_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698