| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "net/base/host_resolver_proc.h" | 5 #include "net/base/host_resolver_proc.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <ws2tcpip.h> | 10 #include <ws2tcpip.h> |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 // universal and even patched systems such as Jaunty appear to need calls | 70 // universal and even patched systems such as Jaunty appear to need calls |
| 71 // to res_ninit to reload the nameserver information in different threads. | 71 // to res_ninit to reload the nameserver information in different threads. |
| 72 // | 72 // |
| 73 // We adopt the Mozilla solution here which is to call res_ninit when | 73 // We adopt the Mozilla solution here which is to call res_ninit when |
| 74 // lookups fail and to rate limit the reloading to once per second per | 74 // lookups fail and to rate limit the reloading to once per second per |
| 75 // thread. | 75 // thread. |
| 76 | 76 |
| 77 // Keep a timer per calling thread to rate limit the calling of res_ninit. | 77 // Keep a timer per calling thread to rate limit the calling of res_ninit. |
| 78 class DnsReloadTimer { | 78 class DnsReloadTimer { |
| 79 public: | 79 public: |
| 80 DnsReloadTimer() { |
| 81 tls_index_.Initialize(SlotReturnFunction); |
| 82 } |
| 83 |
| 84 ~DnsReloadTimer() { } |
| 85 |
| 80 // Check if the timer for the calling thread has expired. When no | 86 // Check if the timer for the calling thread has expired. When no |
| 81 // timer exists for the calling thread, create one. | 87 // timer exists for the calling thread, create one. |
| 82 bool Expired() { | 88 bool Expired() { |
| 83 const base::TimeDelta kRetryTime = base::TimeDelta::FromSeconds(1); | 89 const base::TimeDelta kRetryTime = base::TimeDelta::FromSeconds(1); |
| 84 base::TimeTicks now = base::TimeTicks::Now(); | 90 base::TimeTicks now = base::TimeTicks::Now(); |
| 85 base::TimeTicks* timer_ptr = | 91 base::TimeTicks* timer_ptr = |
| 86 static_cast<base::TimeTicks*>(tls_index_.Get()); | 92 static_cast<base::TimeTicks*>(tls_index_.Get()); |
| 87 | 93 |
| 88 if (!timer_ptr) { | 94 if (!timer_ptr) { |
| 89 timer_ptr = new base::TimeTicks(); | 95 timer_ptr = new base::TimeTicks(); |
| 90 *timer_ptr = base::TimeTicks::Now(); | 96 *timer_ptr = base::TimeTicks::Now(); |
| 91 tls_index_.Set(timer_ptr); | 97 tls_index_.Set(timer_ptr); |
| 92 // Return true to reload dns info on the first call for each thread. | 98 // Return true to reload dns info on the first call for each thread. |
| 93 return true; | 99 return true; |
| 94 } else if (now - *timer_ptr > kRetryTime) { | 100 } else if (now - *timer_ptr > kRetryTime) { |
| 95 *timer_ptr = now; | 101 *timer_ptr = now; |
| 96 return true; | 102 return true; |
| 97 } else { | 103 } else { |
| 98 return false; | 104 return false; |
| 99 } | 105 } |
| 100 } | 106 } |
| 101 | 107 |
| 102 // Free the allocated timer. | 108 // Free the allocated timer. |
| 103 static void SlotReturnFunction(void* data) { | 109 static void SlotReturnFunction(void* data) { |
| 104 base::TimeTicks* tls_data = static_cast<base::TimeTicks*>(data); | 110 base::TimeTicks* tls_data = static_cast<base::TimeTicks*>(data); |
| 105 delete tls_data; | 111 delete tls_data; |
| 106 } | 112 } |
| 107 | 113 |
| 108 private: | 114 private: |
| 109 friend struct DefaultSingletonTraits<DnsReloadTimer>; | |
| 110 | |
| 111 DnsReloadTimer() { | |
| 112 tls_index_.Initialize(SlotReturnFunction); | |
| 113 } | |
| 114 | |
| 115 ~DnsReloadTimer() { | |
| 116 SlotReturnFunction(tls_index_.Get()); | |
| 117 tls_index_.Free(); | |
| 118 } | |
| 119 | |
| 120 // We use thread local storage to identify which base::TimeTicks to | 115 // We use thread local storage to identify which base::TimeTicks to |
| 121 // interact with. | 116 // interact with. |
| 122 static ThreadLocalStorage::Slot tls_index_ ; | 117 static ThreadLocalStorage::Slot tls_index_ ; |
| 123 | 118 |
| 124 DISALLOW_COPY_AND_ASSIGN(DnsReloadTimer); | 119 DISALLOW_COPY_AND_ASSIGN(DnsReloadTimer); |
| 125 }; | 120 }; |
| 126 | 121 |
| 127 // A TLS slot to the TimeTicks for the current thread. | 122 // A TLS slot to the TimeTicks for the current thread. |
| 128 // static | 123 // static |
| 129 ThreadLocalStorage::Slot DnsReloadTimer::tls_index_(base::LINKER_INITIALIZED); | 124 ThreadLocalStorage::Slot DnsReloadTimer::tls_index_(base::LINKER_INITIALIZED); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 #endif | 194 #endif |
| 200 | 195 |
| 201 if (err) | 196 if (err) |
| 202 return ERR_NAME_NOT_RESOLVED; | 197 return ERR_NAME_NOT_RESOLVED; |
| 203 | 198 |
| 204 addrlist->Adopt(ai); | 199 addrlist->Adopt(ai); |
| 205 return OK; | 200 return OK; |
| 206 } | 201 } |
| 207 | 202 |
| 208 } // namespace net | 203 } // namespace net |
| OLD | NEW |