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

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

Issue 194065: Initial commit of sync engine code to browser/sync.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixes to gtest include path, reverted syncapi. Created 11 years, 3 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
Property Changes:
Added: svn:eol-style
+ LF
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 #ifdef POSIX
8 #include <arpa/inet.h>
9 #include <netinet/in.h>
10 #include <netinet/ip.h>
11 #include <netdb.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
14 #endif // POSIX
15
16 #include <vector>
17
18 #include "chrome/browser/sync/notifier/base/nethelpers.h"
19 #include "chrome/browser/sync/notifier/gaia_auth/inet_aton.h"
20 #include "talk/base/byteorder.h"
21 #include "talk/base/common.h"
22 #include "talk/base/logging.h"
23 #include "talk/base/socketaddress.h"
24 #include "talk/base/thread.h"
25
26 enum { MSG_TIMEOUT = talk_base::SignalThread::ST_MSG_FIRST_AVAILABLE };
27
28 #ifndef WIN32
29 const int WSAHOST_NOT_FOUND = 11001; // follows the format in winsock2.h
30 #endif // WIN32
31
32 namespace notifier {
33
34 AsyncDNSLookup::AsyncDNSLookup(const talk_base::SocketAddress& server)
35 : server_(new talk_base::SocketAddress(server)),
36 error_(0) {
37 // Timeout after 5 seconds.
38 talk_base::Thread::Current()->PostDelayed(5000, this, MSG_TIMEOUT);
39 }
40
41 AsyncDNSLookup::~AsyncDNSLookup() {
42 }
43
44 void AsyncDNSLookup::DoWork() {
45 std::string hostname(server_->IPAsString());
46
47 in_addr addr;
48 if (inet_aton(hostname.c_str(), &addr)) {
49 talk_base::CritScope scope(&cs_);
50 ip_list_.push_back(talk_base::NetworkToHost32(addr.s_addr));
51 } else {
52 LOG_F(LS_VERBOSE) << "(" << hostname << ")";
53 hostent ent;
54 char buffer[8192];
55 int errcode = 0;
56 hostent* host = SafeGetHostByName(hostname.c_str(), &ent,
57 buffer, sizeof(buffer),
58 &errcode);
59 talk_base::Thread::Current()->Clear(this, MSG_TIMEOUT);
60 if (host) {
61 talk_base::CritScope scope(&cs_);
62
63 // Check to see if this already timed out.
64 if (error_ == 0) {
65 for (int index = 0; true; ++index) {
66 uint32* addr = reinterpret_cast<uint32*>(host->h_addr_list[index]);
67 if (addr == 0) { // 0 = end of list
68 break;
69 }
70 uint32 ip = talk_base::NetworkToHost32(*addr);
71 LOG_F(LS_VERBOSE) << "(" << hostname << ") resolved to: "
72 << talk_base::SocketAddress::IPToString(ip);
73 ip_list_.push_back(ip);
74 }
75 // Maintain the invariant that either the list is not empty
76 // or the error is non zero when we are done with processing
77 // the dnslookup.
78 if (ip_list_.empty() && error_ == 0) {
79 error_ = WSAHOST_NOT_FOUND;
80 }
81 }
82 FreeHostEnt(host);
83 } else {
84 { // Scoping for the critical section.
85 talk_base::CritScope scope(&cs_);
86
87 // Check to see if this already timed out.
88 if (error_ == 0) {
89 error_ = errcode;
90 }
91 }
92 LOG_F(LS_ERROR) << "(" << hostname << ") error: " << error_;
93 }
94 }
95 }
96
97 void AsyncDNSLookup::OnMessage(talk_base::Message* message) {
98 ASSERT(message);
99 if (message->message_id == MSG_TIMEOUT) {
100 OnTimeout();
101 } else {
102 talk_base::SignalThread::OnMessage(message);
103 }
104 }
105
106 void AsyncDNSLookup::OnTimeout() {
107 // Allow the scope for the critical section to be the whole
108 // method, just to be sure that the worker thread can't exit
109 // while we are doing SignalWorkDone (because that could possibly
110 // cause the class to be deleted).
111 talk_base::CritScope scope(&cs_);
112
113 // Check to see if the ip list was already filled (or errored out).
114 if (!ip_list_.empty() || error_ != 0) {
115 return;
116 }
117
118 // Worker thread is taking too long so timeout.
119 error_ = WSAHOST_NOT_FOUND;
120
121 // Rely on the caller to do the Release/Destroy.
122 //
123 // Doing this signal while holding cs_ won't cause a deadlock because
124 // the AsyncDNSLookup::DoWork thread doesn't have any locks at this point,
125 // and it is the only thread being held up by this.
126 SignalWorkDone(this);
127
128 // Ensure that no more "WorkDone" signaling is done.
129 // Don't call Release or Destroy since that was already done
130 // by the callback.
131 SignalWorkDone.disconnect_all();
132 }
idana 2009/09/10 05:44:37 Add blank line.
133 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698