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

Side by Side Diff: chrome/browser/sync/notifier/base/async_dns_lookup.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) 2009 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_dns_lookup.h"
6
7 #include "build/build_config.h"
8
9 #if defined(OS_POSIX)
10 #include <arpa/inet.h>
11 #include <netdb.h>
12 #include <netinet/in_systm.h>
13 #include <netinet/in.h>
14 #include <netinet/ip.h>
15 #include <sys/socket.h>
16 #include <sys/types.h>
17 #endif // defined(OS_POSIX)
18
19 // Apparently, inet_aton() is available for Windows, but just not
20 // declared anywhere. We'd use inet_pton(), but it's Vista-only.
21 #if defined(OS_WIN)
22 int inet_aton(const char* cp, struct in_addr* inp);
23 #endif // defined(OS_WIN)
24
25 #include <vector>
26
27 #include "base/basictypes.h"
28 #include "base/logging.h"
29 #include "chrome/browser/sync/notifier/base/nethelpers.h"
30 #include "talk/base/byteorder.h"
31 #include "talk/base/common.h"
32 #include "talk/base/socketaddress.h"
33 #include "talk/base/thread.h"
34
35 enum { MSG_TIMEOUT = talk_base::SignalThread::ST_MSG_FIRST_AVAILABLE };
36
37 #ifndef WIN32
38 const int WSAHOST_NOT_FOUND = 11001; // Follows the format in winsock2.h.
39 #endif // WIN32
40
41 namespace notifier {
42
43 AsyncDNSLookup::AsyncDNSLookup(const talk_base::SocketAddress& server)
44 : server_(new talk_base::SocketAddress(server)),
45 error_(0) {
46 // Timeout after 5 seconds.
47 talk_base::Thread::Current()->PostDelayed(5000, this, MSG_TIMEOUT);
48 }
49
50 AsyncDNSLookup::~AsyncDNSLookup() {
51 }
52
53 void AsyncDNSLookup::DoWork() {
54 std::string hostname(server_->IPAsString());
55
56 in_addr addr;
57 if (inet_aton(hostname.c_str(), &addr)) {
58 talk_base::CritScope scope(&cs_);
59 ip_list_.push_back(talk_base::NetworkToHost32(addr.s_addr));
60 } else {
61 LOG(INFO) << "(" << hostname << ")";
62 hostent ent;
63 char buffer[8192];
64 int errcode = 0;
65 hostent* host = SafeGetHostByName(hostname.c_str(), &ent,
66 buffer, sizeof(buffer),
67 &errcode);
68 talk_base::Thread::Current()->Clear(this, MSG_TIMEOUT);
69 if (host) {
70 talk_base::CritScope scope(&cs_);
71
72 // Check to see if this already timed out.
73 if (error_ == 0) {
74 for (int index = 0; true; ++index) {
75 uint32* addr = reinterpret_cast<uint32*>(host->h_addr_list[index]);
76 if (addr == 0) { // 0 = end of list.
77 break;
78 }
79 uint32 ip = talk_base::NetworkToHost32(*addr);
80 LOG(INFO) << "(" << hostname << ") resolved to: "
81 << talk_base::SocketAddress::IPToString(ip);
82 ip_list_.push_back(ip);
83 }
84 // Maintain the invariant that either the list is not empty or the
85 // error is non zero when we are done with processing the dnslookup.
86 if (ip_list_.empty() && error_ == 0) {
87 error_ = WSAHOST_NOT_FOUND;
88 }
89 }
90 FreeHostEnt(host);
91 } else {
92 { // Scoping for the critical section.
93 talk_base::CritScope scope(&cs_);
94
95 // Check to see if this already timed out.
96 if (error_ == 0) {
97 error_ = errcode;
98 }
99 }
100 LOG(ERROR) << "(" << hostname << ") error: " << error_;
101 }
102 }
103 }
104
105 void AsyncDNSLookup::OnMessage(talk_base::Message* message) {
106 ASSERT(message);
107 if (message->message_id == MSG_TIMEOUT) {
108 OnTimeout();
109 } else {
110 talk_base::SignalThread::OnMessage(message);
111 }
112 }
113
114 void AsyncDNSLookup::OnTimeout() {
115 // Allow the scope for the critical section to be the whole method, just to
116 // be sure that the worker thread can't exit while we are doing
117 // SignalWorkDone (because that could possibly cause the class to be
118 // deleted).
119 talk_base::CritScope scope(&cs_);
120
121 // Check to see if the ip list was already filled (or errored out).
122 if (!ip_list_.empty() || error_ != 0) {
123 return;
124 }
125
126 // Worker thread is taking too long so timeout.
127 error_ = WSAHOST_NOT_FOUND;
128
129 // Rely on the caller to do the Release/Destroy.
130 //
131 // Doing this signal while holding cs_ won't cause a deadlock because the
132 // AsyncDNSLookup::DoWork thread doesn't have any locks at this point, and it
133 // is the only thread being held up by this.
134 SignalWorkDone(this);
135
136 // Ensure that no more "WorkDone" signaling is done.
137 // Don't call Release or Destroy since that was already done by the callback.
138 SignalWorkDone.disconnect_all();
139 }
140
141 } // namespace notifier
OLDNEW
« no previous file with comments | « chrome/browser/sync/notifier/base/async_dns_lookup.h ('k') | chrome/browser/sync/notifier/base/async_network_alive.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698