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

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

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

Powered by Google App Engine
This is Rietveld 408576698