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

Side by Side Diff: chrome/browser/sync/notifier/base/linux/async_network_alive_linux.cc

Issue 552162: Add an implementation for async_network_alive to Linux (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 #include "chrome/browser/sync/notifier/base/async_network_alive.h"
6
7 #include <sys/socket.h>
8 #include <asm/types.h>
9 #include <linux/netlink.h>
10 #include <linux/rtnetlink.h>
11
12 #include "base/logging.h"
13 #include "talk/base/physicalsocketserver.h"
14
15 namespace notifier {
16
17 class AsyncNetworkAliveLinux : public AsyncNetworkAlive {
18 public:
19 AsyncNetworkAliveLinux() {
20 if (pipe(exit_pipe_) == -1) {
21 PLOG(ERROR) << "Could not create pipe for exit signal.";
22 exit_pipe_[0] = 0;
23 exit_pipe_[1] = 0;
24 }
25 }
26
27 virtual ~AsyncNetworkAliveLinux() {
28 if (exit_pipe_[1]) {
29 close(exit_pipe_[1]);
30 }
31 }
32
33 protected:
34 // SignalThread Interface
35 virtual void DoWork() {
36 if (!exit_pipe_[0]) {
37 // If we don't have an exit flag to listen for, set the error flag and
38 // abort.
39 error_ = true;
40 return;
41 }
42
43 // This function listens for changes to network interfaces, and link state.
44 // It's copied from syncapi.cc.
45 struct sockaddr_nl socket_address;
46
47 memset(&socket_address, 0, sizeof(socket_address));
48 socket_address.nl_family = AF_NETLINK;
49 socket_address.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
50
51 // NETLINK_ROUTE is the protocol used to update the kernel routing table.
52 int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
53 bind(fd, (struct sockaddr *) &socket_address, sizeof(socket_address));
54
55 fd_set rdfs;
56 FD_ZERO(&rdfs);
57 FD_SET(fd, &rdfs);
58 FD_SET(exit_pipe_[0], &rdfs);
59
60 int max_fd = fd > exit_pipe_[0] ? fd : exit_pipe_[0];
61
62 int result = select(max_fd + 1, &rdfs, NULL, NULL, NULL);
63
64 if (result <= 0) {
65 error_ = true;
66 PLOG(ERROR) << "select() returned unexpected result " << result;
67 close(fd);
68 close(exit_pipe_[0]);
69 return;
70 }
71
72 // Since we recieved a change from the socket, read the change in.
73 if (FD_ISSET(fd, &rdfs)) {
74 char buf[4096];
75 struct iovec iov = { buf, sizeof(buf) };
76 struct sockaddr_nl sa;
77
78 struct msghdr msg = { (void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
79 recvmsg(fd, &msg, 0);
80 }
81
82 close(fd);
83
84 // If exit_pipe was written to, we must be shutting down.
85 if (FD_ISSET(exit_pipe_[0], &rdfs)) {
86 alive_ = false;
87 error_ = true;
88 close(exit_pipe_[0]);
89 return;
90 }
91
92 // If there is an active connection, check that talk.google.com:5222
93 // is reachable.
94 talk_base::PhysicalSocketServer physical;
95 scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM));
96 if (socket->Connect(talk_base::SocketAddress("talk.google.com", 5222))) {
97 alive_ = false;
98 } else {
99 alive_ = true;
100 }
101 }
102
103 virtual void OnWorkStop() {
104 if (exit_pipe_[1]) {
105 char data = 0;
106 // We can't ignore the return value on write(), since that generates a
107 // compile warning. However, since we're exiting, there's nothing we can
108 // do if this fails except to log it.
109 if (write(exit_pipe_[1], &data, 1) == -1) {
110 PLOG(WARNING) << "Error sending error signal to AsyncNetworkAliveLinux";
111 }
112 }
113 }
114
115 private:
116 int exit_pipe_[2];
117 DISALLOW_COPY_AND_ASSIGN(AsyncNetworkAliveLinux);
118 };
119
120 AsyncNetworkAlive* AsyncNetworkAlive::Create() {
121 return new AsyncNetworkAliveLinux();
122 }
123
124 } // namespace notifier
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncapi.cc ('k') | chrome/browser/sync/notifier/base/linux/network_status_detector_task_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698