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

Side by Side Diff: net/proxy/proxy_config_service_linux.cc

Issue 10140010: Use base::MessageLoopProxy instead of MessageLoop in ProxyConfigServiceLinux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/proxy/proxy_config_service_linux.h" 5 #include "net/proxy/proxy_config_service_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #if defined(USE_GCONF) 9 #if defined(USE_GCONF)
10 #include <gconf/gconf-client.h> 10 #include <gconf/gconf-client.h>
(...skipping 12 matching lines...) Expand all
23 23
24 #include <map> 24 #include <map>
25 25
26 #include "base/bind.h" 26 #include "base/bind.h"
27 #include "base/compiler_specific.h" 27 #include "base/compiler_specific.h"
28 #include "base/environment.h" 28 #include "base/environment.h"
29 #include "base/file_path.h" 29 #include "base/file_path.h"
30 #include "base/file_util.h" 30 #include "base/file_util.h"
31 #include "base/logging.h" 31 #include "base/logging.h"
32 #include "base/message_loop.h" 32 #include "base/message_loop.h"
33 #include "base/message_loop_proxy.h"
33 #include "base/nix/xdg_util.h" 34 #include "base/nix/xdg_util.h"
34 #include "base/string_number_conversions.h" 35 #include "base/string_number_conversions.h"
35 #include "base/string_tokenizer.h" 36 #include "base/string_tokenizer.h"
36 #include "base/string_util.h" 37 #include "base/string_util.h"
37 #include "base/threading/thread_restrictions.h" 38 #include "base/threading/thread_restrictions.h"
38 #include "base/timer.h" 39 #include "base/timer.h"
39 #include "googleurl/src/url_canon.h" 40 #include "googleurl/src/url_canon.h"
40 #include "net/base/net_errors.h" 41 #include "net/base/net_errors.h"
41 #include "net/http/http_util.h" 42 #include "net/http/http_util.h"
42 #include "net/proxy/proxy_config.h" 43 #include "net/proxy/proxy_config.h"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 206 }
206 207
207 virtual ~SettingGetterImplGConf() { 208 virtual ~SettingGetterImplGConf() {
208 // client_ should have been released before now, from 209 // client_ should have been released before now, from
209 // Delegate::OnDestroy(), while running on the UI thread. However 210 // Delegate::OnDestroy(), while running on the UI thread. However
210 // on exiting the process, it may happen that Delegate::OnDestroy() 211 // on exiting the process, it may happen that Delegate::OnDestroy()
211 // task is left pending on the glib loop after the loop was quit, 212 // task is left pending on the glib loop after the loop was quit,
212 // and pending tasks may then be deleted without being run. 213 // and pending tasks may then be deleted without being run.
213 if (client_) { 214 if (client_) {
214 // gconf client was not cleaned up. 215 // gconf client was not cleaned up.
215 if (MessageLoop::current() == loop_) { 216 if (loop_->BelongsToCurrentThread()) {
216 // We are on the UI thread so we can clean it safely. This is 217 // We are on the UI thread so we can clean it safely. This is
217 // the case at least for ui_tests running under Valgrind in 218 // the case at least for ui_tests running under Valgrind in
218 // bug 16076. 219 // bug 16076.
219 VLOG(1) << "~SettingGetterImplGConf: releasing gconf client"; 220 VLOG(1) << "~SettingGetterImplGConf: releasing gconf client";
220 ShutDown(); 221 ShutDown();
221 } else { 222 } else {
222 // This is very bad! We are deleting the setting getter but we're not on 223 // This is very bad! We are deleting the setting getter but we're not on
223 // the UI thread. This is not supposed to happen: the setting getter is 224 // the UI thread. This is not supposed to happen: the setting getter is
224 // owned by the proxy config service's delegate, which is supposed to be 225 // owned by the proxy config service's delegate, which is supposed to be
225 // destroyed on the UI thread only. We will get change notifications to 226 // destroyed on the UI thread only. We will get change notifications to
226 // a deleted object if we continue here, so fail now. 227 // a deleted object if we continue here, so fail now.
227 LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!"; 228 LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!";
228 } 229 }
229 } 230 }
230 DCHECK(!client_); 231 DCHECK(!client_);
231 } 232 }
232 233
233 virtual bool Init(MessageLoop* glib_default_loop, 234 virtual bool Init(base::MessageLoopProxy* glib_default_loop,
234 MessageLoopForIO* file_loop) OVERRIDE { 235 MessageLoopForIO* file_loop) OVERRIDE {
235 DCHECK(MessageLoop::current() == glib_default_loop); 236 DCHECK(glib_default_loop->BelongsToCurrentThread());
236 DCHECK(!client_); 237 DCHECK(!client_);
237 DCHECK(!loop_); 238 DCHECK(!loop_);
238 loop_ = glib_default_loop; 239 loop_ = glib_default_loop;
239 client_ = gconf_client_get_default(); 240 client_ = gconf_client_get_default();
240 if (!client_) { 241 if (!client_) {
241 // It's not clear whether/when this can return NULL. 242 // It's not clear whether/when this can return NULL.
242 LOG(ERROR) << "Unable to create a gconf client"; 243 LOG(ERROR) << "Unable to create a gconf client";
243 loop_ = NULL; 244 loop_ = NULL;
244 return false; 245 return false;
245 } 246 }
(...skipping 18 matching lines...) Expand all
264 g_object_unref(client_); 265 g_object_unref(client_);
265 client_ = NULL; 266 client_ = NULL;
266 loop_ = NULL; 267 loop_ = NULL;
267 return false; 268 return false;
268 } 269 }
269 return true; 270 return true;
270 } 271 }
271 272
272 void ShutDown() { 273 void ShutDown() {
273 if (client_) { 274 if (client_) {
274 DCHECK(MessageLoop::current() == loop_); 275 DCHECK(loop_->BelongsToCurrentThread());
275 // We must explicitly disable gconf notifications here, because the gconf 276 // We must explicitly disable gconf notifications here, because the gconf
276 // client will be shared between all setting getters, and they do not all 277 // client will be shared between all setting getters, and they do not all
277 // have the same lifetimes. (For instance, incognito sessions get their 278 // have the same lifetimes. (For instance, incognito sessions get their
278 // own, which is destroyed when the session ends.) 279 // own, which is destroyed when the session ends.)
279 gconf_client_notify_remove(client_, system_http_proxy_id_); 280 gconf_client_notify_remove(client_, system_http_proxy_id_);
280 gconf_client_notify_remove(client_, system_proxy_id_); 281 gconf_client_notify_remove(client_, system_proxy_id_);
281 gconf_client_remove_dir(client_, "/system/http_proxy", NULL); 282 gconf_client_remove_dir(client_, "/system/http_proxy", NULL);
282 gconf_client_remove_dir(client_, "/system/proxy", NULL); 283 gconf_client_remove_dir(client_, "/system/proxy", NULL);
283 g_object_unref(client_); 284 g_object_unref(client_);
284 client_ = NULL; 285 client_ = NULL;
285 loop_ = NULL; 286 loop_ = NULL;
286 } 287 }
287 } 288 }
288 289
289 bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate) { 290 bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate) {
290 DCHECK(client_); 291 DCHECK(client_);
291 DCHECK(MessageLoop::current() == loop_); 292 DCHECK(loop_->BelongsToCurrentThread());
292 GError* error = NULL; 293 GError* error = NULL;
293 notify_delegate_ = delegate; 294 notify_delegate_ = delegate;
294 // We have to keep track of the IDs returned by gconf_client_notify_add() so 295 // We have to keep track of the IDs returned by gconf_client_notify_add() so
295 // that we can remove them in ShutDown(). (Otherwise, notifications will be 296 // that we can remove them in ShutDown(). (Otherwise, notifications will be
296 // delivered to this object after it is deleted, which is bad, m'kay?) 297 // delivered to this object after it is deleted, which is bad, m'kay?)
297 system_proxy_id_ = gconf_client_notify_add( 298 system_proxy_id_ = gconf_client_notify_add(
298 client_, "/system/proxy", 299 client_, "/system/proxy",
299 OnGConfChangeNotification, this, 300 OnGConfChangeNotification, this,
300 NULL, &error); 301 NULL, &error);
301 if (error == NULL) { 302 if (error == NULL) {
302 system_http_proxy_id_ = gconf_client_notify_add( 303 system_http_proxy_id_ = gconf_client_notify_add(
303 client_, "/system/http_proxy", 304 client_, "/system/http_proxy",
304 OnGConfChangeNotification, this, 305 OnGConfChangeNotification, this,
305 NULL, &error); 306 NULL, &error);
306 } 307 }
307 if (error != NULL) { 308 if (error != NULL) {
308 LOG(ERROR) << "Error requesting gconf notifications: " << error->message; 309 LOG(ERROR) << "Error requesting gconf notifications: " << error->message;
309 g_error_free(error); 310 g_error_free(error);
310 ShutDown(); 311 ShutDown();
311 return false; 312 return false;
312 } 313 }
313 // Simulate a change to avoid possibly losing updates before this point. 314 // Simulate a change to avoid possibly losing updates before this point.
314 OnChangeNotification(); 315 OnChangeNotification();
315 return true; 316 return true;
316 } 317 }
317 318
318 virtual MessageLoop* GetNotificationLoop() OVERRIDE { 319 virtual base::MessageLoopProxy* GetNotificationLoop() OVERRIDE {
319 return loop_; 320 return loop_;
320 } 321 }
321 322
322 virtual const char* GetDataSource() OVERRIDE { 323 virtual const char* GetDataSource() OVERRIDE {
323 return "gconf"; 324 return "gconf";
324 } 325 }
325 326
326 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { 327 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
327 switch (key) { 328 switch (key) {
328 case PROXY_MODE: 329 case PROXY_MODE:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 return false; 379 return false;
379 } 380 }
380 381
381 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE { 382 virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
382 return false; 383 return false;
383 } 384 }
384 385
385 private: 386 private:
386 bool GetStringByPath(const char* key, std::string* result) { 387 bool GetStringByPath(const char* key, std::string* result) {
387 DCHECK(client_); 388 DCHECK(client_);
388 DCHECK(MessageLoop::current() == loop_); 389 DCHECK(loop_->BelongsToCurrentThread());
389 GError* error = NULL; 390 GError* error = NULL;
390 gchar* value = gconf_client_get_string(client_, key, &error); 391 gchar* value = gconf_client_get_string(client_, key, &error);
391 if (HandleGError(error, key)) 392 if (HandleGError(error, key))
392 return false; 393 return false;
393 if (!value) 394 if (!value)
394 return false; 395 return false;
395 *result = value; 396 *result = value;
396 g_free(value); 397 g_free(value);
397 return true; 398 return true;
398 } 399 }
399 bool GetBoolByPath(const char* key, bool* result) { 400 bool GetBoolByPath(const char* key, bool* result) {
400 DCHECK(client_); 401 DCHECK(client_);
401 DCHECK(MessageLoop::current() == loop_); 402 DCHECK(loop_->BelongsToCurrentThread());
402 GError* error = NULL; 403 GError* error = NULL;
403 // We want to distinguish unset values from values defaulting to 404 // We want to distinguish unset values from values defaulting to
404 // false. For that we need to use the type-generic 405 // false. For that we need to use the type-generic
405 // gconf_client_get() rather than gconf_client_get_bool(). 406 // gconf_client_get() rather than gconf_client_get_bool().
406 GConfValue* gconf_value = gconf_client_get(client_, key, &error); 407 GConfValue* gconf_value = gconf_client_get(client_, key, &error);
407 if (HandleGError(error, key)) 408 if (HandleGError(error, key))
408 return false; 409 return false;
409 if (!gconf_value) { 410 if (!gconf_value) {
410 // Unset. 411 // Unset.
411 return false; 412 return false;
412 } 413 }
413 if (gconf_value->type != GCONF_VALUE_BOOL) { 414 if (gconf_value->type != GCONF_VALUE_BOOL) {
414 gconf_value_free(gconf_value); 415 gconf_value_free(gconf_value);
415 return false; 416 return false;
416 } 417 }
417 gboolean bool_value = gconf_value_get_bool(gconf_value); 418 gboolean bool_value = gconf_value_get_bool(gconf_value);
418 *result = static_cast<bool>(bool_value); 419 *result = static_cast<bool>(bool_value);
419 gconf_value_free(gconf_value); 420 gconf_value_free(gconf_value);
420 return true; 421 return true;
421 } 422 }
422 bool GetIntByPath(const char* key, int* result) { 423 bool GetIntByPath(const char* key, int* result) {
423 DCHECK(client_); 424 DCHECK(client_);
424 DCHECK(MessageLoop::current() == loop_); 425 DCHECK(loop_->BelongsToCurrentThread());
425 GError* error = NULL; 426 GError* error = NULL;
426 int value = gconf_client_get_int(client_, key, &error); 427 int value = gconf_client_get_int(client_, key, &error);
427 if (HandleGError(error, key)) 428 if (HandleGError(error, key))
428 return false; 429 return false;
429 // We don't bother to distinguish an unset value because callers 430 // We don't bother to distinguish an unset value because callers
430 // don't care. 0 is returned if unset. 431 // don't care. 0 is returned if unset.
431 *result = value; 432 *result = value;
432 return true; 433 return true;
433 } 434 }
434 bool GetStringListByPath(const char* key, std::vector<std::string>* result) { 435 bool GetStringListByPath(const char* key, std::vector<std::string>* result) {
435 DCHECK(client_); 436 DCHECK(client_);
436 DCHECK(MessageLoop::current() == loop_); 437 DCHECK(loop_->BelongsToCurrentThread());
437 GError* error = NULL; 438 GError* error = NULL;
438 GSList* list = gconf_client_get_list(client_, key, 439 GSList* list = gconf_client_get_list(client_, key,
439 GCONF_VALUE_STRING, &error); 440 GCONF_VALUE_STRING, &error);
440 if (HandleGError(error, key)) 441 if (HandleGError(error, key))
441 return false; 442 return false;
442 if (!list) 443 if (!list)
443 return false; 444 return false;
444 for (GSList *it = list; it; it = it->next) { 445 for (GSList *it = list; it; it = it->next) {
445 result->push_back(static_cast<char*>(it->data)); 446 result->push_back(static_cast<char*>(it->data));
446 g_free(it->data); 447 g_free(it->data);
447 } 448 }
448 g_slist_free(list); 449 g_slist_free(list);
449 return true; 450 return true;
450 } 451 }
451 452
452 // Logs and frees a glib error. Returns false if there was no error 453 // Logs and frees a glib error. Returns false if there was no error
453 // (error is NULL). 454 // (error is NULL).
454 bool HandleGError(GError* error, const char* key) { 455 bool HandleGError(GError* error, const char* key) {
455 if (error != NULL) { 456 if (error != NULL) {
456 LOG(ERROR) << "Error getting gconf value for " << key 457 LOG(ERROR) << "Error getting gconf value for " << key
457 << ": " << error->message; 458 << ": " << error->message;
458 g_error_free(error); 459 g_error_free(error);
459 return true; 460 return true;
460 } 461 }
461 return false; 462 return false;
462 } 463 }
463 464
464 // This is the callback from the debounce timer. 465 // This is the callback from the debounce timer.
465 void OnDebouncedNotification() { 466 void OnDebouncedNotification() {
466 DCHECK(MessageLoop::current() == loop_); 467 DCHECK(loop_->BelongsToCurrentThread());
467 CHECK(notify_delegate_); 468 CHECK(notify_delegate_);
468 // Forward to a method on the proxy config service delegate object. 469 // Forward to a method on the proxy config service delegate object.
469 notify_delegate_->OnCheckProxyConfigSettings(); 470 notify_delegate_->OnCheckProxyConfigSettings();
470 } 471 }
471 472
472 void OnChangeNotification() { 473 void OnChangeNotification() {
473 // We don't use Reset() because the timer may not yet be running. 474 // We don't use Reset() because the timer may not yet be running.
474 // (In that case Stop() is a no-op.) 475 // (In that case Stop() is a no-op.)
475 debounce_timer_.Stop(); 476 debounce_timer_.Stop();
476 debounce_timer_.Start(FROM_HERE, 477 debounce_timer_.Start(FROM_HERE,
(...skipping 17 matching lines...) Expand all
494 // will need in order to later call gconf_client_notify_remove(). 495 // will need in order to later call gconf_client_notify_remove().
495 guint system_proxy_id_; 496 guint system_proxy_id_;
496 guint system_http_proxy_id_; 497 guint system_http_proxy_id_;
497 498
498 ProxyConfigServiceLinux::Delegate* notify_delegate_; 499 ProxyConfigServiceLinux::Delegate* notify_delegate_;
499 base::OneShotTimer<SettingGetterImplGConf> debounce_timer_; 500 base::OneShotTimer<SettingGetterImplGConf> debounce_timer_;
500 501
501 // Message loop of the thread that we make gconf calls on. It should 502 // Message loop of the thread that we make gconf calls on. It should
502 // be the UI thread and all our methods should be called on this 503 // be the UI thread and all our methods should be called on this
503 // thread. Only for assertions. 504 // thread. Only for assertions.
504 MessageLoop* loop_; 505 scoped_refptr<base::MessageLoopProxy> loop_;
505 506
506 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); 507 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf);
507 }; 508 };
508 #endif // defined(USE_GCONF) 509 #endif // defined(USE_GCONF)
509 510
510 #if defined(USE_GIO) 511 #if defined(USE_GIO)
511 // This setting getter uses gsettings, as used in most GNOME 3 desktops. 512 // This setting getter uses gsettings, as used in most GNOME 3 desktops.
512 class SettingGetterImplGSettings 513 class SettingGetterImplGSettings
513 : public ProxyConfigServiceLinux::SettingGetter { 514 : public ProxyConfigServiceLinux::SettingGetter {
514 public: 515 public:
(...skipping 19 matching lines...) Expand all
534 535
535 virtual ~SettingGetterImplGSettings() { 536 virtual ~SettingGetterImplGSettings() {
536 // client_ should have been released before now, from 537 // client_ should have been released before now, from
537 // Delegate::OnDestroy(), while running on the UI thread. However 538 // Delegate::OnDestroy(), while running on the UI thread. However
538 // on exiting the process, it may happen that 539 // on exiting the process, it may happen that
539 // Delegate::OnDestroy() task is left pending on the glib loop 540 // Delegate::OnDestroy() task is left pending on the glib loop
540 // after the loop was quit, and pending tasks may then be deleted 541 // after the loop was quit, and pending tasks may then be deleted
541 // without being run. 542 // without being run.
542 if (client_) { 543 if (client_) {
543 // gconf client was not cleaned up. 544 // gconf client was not cleaned up.
544 if (MessageLoop::current() == loop_) { 545 if (loop_->BelongsToCurrentThread()) {
545 // We are on the UI thread so we can clean it safely. This is 546 // We are on the UI thread so we can clean it safely. This is
546 // the case at least for ui_tests running under Valgrind in 547 // the case at least for ui_tests running under Valgrind in
547 // bug 16076. 548 // bug 16076.
548 VLOG(1) << "~SettingGetterImplGSettings: releasing gsettings client"; 549 VLOG(1) << "~SettingGetterImplGSettings: releasing gsettings client";
549 ShutDown(); 550 ShutDown();
550 } else { 551 } else {
551 LOG(WARNING) << "~SettingGetterImplGSettings: leaking gsettings client"; 552 LOG(WARNING) << "~SettingGetterImplGSettings: leaking gsettings client";
552 client_ = NULL; 553 client_ = NULL;
553 } 554 }
554 } 555 }
(...skipping 12 matching lines...) Expand all
567 if (strcmp(schema_name, static_cast<const char*>(*schemas)) == 0) 568 if (strcmp(schema_name, static_cast<const char*>(*schemas)) == 0)
568 return true; 569 return true;
569 schemas++; 570 schemas++;
570 } 571 }
571 return false; 572 return false;
572 } 573 }
573 574
574 // LoadAndCheckVersion() must be called *before* Init()! 575 // LoadAndCheckVersion() must be called *before* Init()!
575 bool LoadAndCheckVersion(base::Environment* env); 576 bool LoadAndCheckVersion(base::Environment* env);
576 577
577 virtual bool Init(MessageLoop* glib_default_loop, 578 virtual bool Init(base::MessageLoopProxy* glib_default_loop,
578 MessageLoopForIO* file_loop) OVERRIDE { 579 MessageLoopForIO* file_loop) OVERRIDE {
579 DCHECK(MessageLoop::current() == glib_default_loop); 580 DCHECK(glib_default_loop->BelongsToCurrentThread());
580 DCHECK(!client_); 581 DCHECK(!client_);
581 DCHECK(!loop_); 582 DCHECK(!loop_);
582 583
583 if (!SchemaExists("org.gnome.system.proxy") || 584 if (!SchemaExists("org.gnome.system.proxy") ||
584 !(client_ = g_settings_new("org.gnome.system.proxy"))) { 585 !(client_ = g_settings_new("org.gnome.system.proxy"))) {
585 // It's not clear whether/when this can return NULL. 586 // It's not clear whether/when this can return NULL.
586 LOG(ERROR) << "Unable to create a gsettings client"; 587 LOG(ERROR) << "Unable to create a gsettings client";
587 return false; 588 return false;
588 } 589 }
589 loop_ = glib_default_loop; 590 loop_ = glib_default_loop;
590 // We assume these all work if the above call worked. 591 // We assume these all work if the above call worked.
591 http_client_ = g_settings_get_child(client_, "http"); 592 http_client_ = g_settings_get_child(client_, "http");
592 https_client_ = g_settings_get_child(client_, "https"); 593 https_client_ = g_settings_get_child(client_, "https");
593 ftp_client_ = g_settings_get_child(client_, "ftp"); 594 ftp_client_ = g_settings_get_child(client_, "ftp");
594 socks_client_ = g_settings_get_child(client_, "socks"); 595 socks_client_ = g_settings_get_child(client_, "socks");
595 DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_); 596 DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_);
596 return true; 597 return true;
597 } 598 }
598 599
599 void ShutDown() { 600 void ShutDown() {
600 if (client_) { 601 if (client_) {
601 DCHECK(MessageLoop::current() == loop_); 602 DCHECK(loop_->BelongsToCurrentThread());
602 // This also disables gsettings notifications. 603 // This also disables gsettings notifications.
603 g_object_unref(socks_client_); 604 g_object_unref(socks_client_);
604 g_object_unref(ftp_client_); 605 g_object_unref(ftp_client_);
605 g_object_unref(https_client_); 606 g_object_unref(https_client_);
606 g_object_unref(http_client_); 607 g_object_unref(http_client_);
607 g_object_unref(client_); 608 g_object_unref(client_);
608 // We only need to null client_ because it's the only one that we check. 609 // We only need to null client_ because it's the only one that we check.
609 client_ = NULL; 610 client_ = NULL;
610 loop_ = NULL; 611 loop_ = NULL;
611 } 612 }
612 } 613 }
613 614
614 bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate) { 615 bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate) {
615 DCHECK(client_); 616 DCHECK(client_);
616 DCHECK(MessageLoop::current() == loop_); 617 DCHECK(loop_->BelongsToCurrentThread());
617 notify_delegate_ = delegate; 618 notify_delegate_ = delegate;
618 // We could watch for the change-event signal instead of changed, but 619 // We could watch for the change-event signal instead of changed, but
619 // since we have to watch more than one object, we'd still have to 620 // since we have to watch more than one object, we'd still have to
620 // debounce change notifications. This is conceptually simpler. 621 // debounce change notifications. This is conceptually simpler.
621 g_signal_connect(G_OBJECT(client_), "changed", 622 g_signal_connect(G_OBJECT(client_), "changed",
622 G_CALLBACK(OnGSettingsChangeNotification), this); 623 G_CALLBACK(OnGSettingsChangeNotification), this);
623 g_signal_connect(G_OBJECT(http_client_), "changed", 624 g_signal_connect(G_OBJECT(http_client_), "changed",
624 G_CALLBACK(OnGSettingsChangeNotification), this); 625 G_CALLBACK(OnGSettingsChangeNotification), this);
625 g_signal_connect(G_OBJECT(https_client_), "changed", 626 g_signal_connect(G_OBJECT(https_client_), "changed",
626 G_CALLBACK(OnGSettingsChangeNotification), this); 627 G_CALLBACK(OnGSettingsChangeNotification), this);
627 g_signal_connect(G_OBJECT(ftp_client_), "changed", 628 g_signal_connect(G_OBJECT(ftp_client_), "changed",
628 G_CALLBACK(OnGSettingsChangeNotification), this); 629 G_CALLBACK(OnGSettingsChangeNotification), this);
629 g_signal_connect(G_OBJECT(socks_client_), "changed", 630 g_signal_connect(G_OBJECT(socks_client_), "changed",
630 G_CALLBACK(OnGSettingsChangeNotification), this); 631 G_CALLBACK(OnGSettingsChangeNotification), this);
631 // Simulate a change to avoid possibly losing updates before this point. 632 // Simulate a change to avoid possibly losing updates before this point.
632 OnChangeNotification(); 633 OnChangeNotification();
633 return true; 634 return true;
634 } 635 }
635 636
636 virtual MessageLoop* GetNotificationLoop() OVERRIDE { 637 virtual base::MessageLoopProxy* GetNotificationLoop() OVERRIDE {
637 return loop_; 638 return loop_;
638 } 639 }
639 640
640 virtual const char* GetDataSource() OVERRIDE { 641 virtual const char* GetDataSource() OVERRIDE {
641 return "gsettings"; 642 return "gsettings";
642 } 643 }
643 644
644 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { 645 virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
645 DCHECK(client_); 646 DCHECK(client_);
646 switch (key) { 647 switch (key) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 if (error) { 738 if (error) {
738 VLOG(1) << "Unable to load symbol " << name << ": " << error; 739 VLOG(1) << "Unable to load symbol " << name << ": " << error;
739 return false; 740 return false;
740 } 741 }
741 return true; 742 return true;
742 } 743 }
743 #endif // defined(DLOPEN_GSETTINGS) 744 #endif // defined(DLOPEN_GSETTINGS)
744 745
745 bool GetStringByPath(GSettings* client, const char* key, 746 bool GetStringByPath(GSettings* client, const char* key,
746 std::string* result) { 747 std::string* result) {
747 DCHECK(MessageLoop::current() == loop_); 748 DCHECK(loop_->BelongsToCurrentThread());
748 gchar* value = g_settings_get_string(client, key); 749 gchar* value = g_settings_get_string(client, key);
749 if (!value) 750 if (!value)
750 return false; 751 return false;
751 *result = value; 752 *result = value;
752 g_free(value); 753 g_free(value);
753 return true; 754 return true;
754 } 755 }
755 bool GetBoolByPath(GSettings* client, const char* key, bool* result) { 756 bool GetBoolByPath(GSettings* client, const char* key, bool* result) {
756 DCHECK(MessageLoop::current() == loop_); 757 DCHECK(loop_->BelongsToCurrentThread());
757 *result = static_cast<bool>(g_settings_get_boolean(client, key)); 758 *result = static_cast<bool>(g_settings_get_boolean(client, key));
758 return true; 759 return true;
759 } 760 }
760 bool GetIntByPath(GSettings* client, const char* key, int* result) { 761 bool GetIntByPath(GSettings* client, const char* key, int* result) {
761 DCHECK(MessageLoop::current() == loop_); 762 DCHECK(loop_->BelongsToCurrentThread());
762 *result = g_settings_get_int(client, key); 763 *result = g_settings_get_int(client, key);
763 return true; 764 return true;
764 } 765 }
765 bool GetStringListByPath(GSettings* client, const char* key, 766 bool GetStringListByPath(GSettings* client, const char* key,
766 std::vector<std::string>* result) { 767 std::vector<std::string>* result) {
767 DCHECK(MessageLoop::current() == loop_); 768 DCHECK(loop_->BelongsToCurrentThread());
768 gchar** list = g_settings_get_strv(client, key); 769 gchar** list = g_settings_get_strv(client, key);
769 if (!list) 770 if (!list)
770 return false; 771 return false;
771 for (size_t i = 0; list[i]; ++i) { 772 for (size_t i = 0; list[i]; ++i) {
772 result->push_back(static_cast<char*>(list[i])); 773 result->push_back(static_cast<char*>(list[i]));
773 g_free(list[i]); 774 g_free(list[i]);
774 } 775 }
775 g_free(list); 776 g_free(list);
776 return true; 777 return true;
777 } 778 }
778 779
779 // This is the callback from the debounce timer. 780 // This is the callback from the debounce timer.
780 void OnDebouncedNotification() { 781 void OnDebouncedNotification() {
781 DCHECK(MessageLoop::current() == loop_); 782 DCHECK(loop_->BelongsToCurrentThread());
782 CHECK(notify_delegate_); 783 CHECK(notify_delegate_);
783 // Forward to a method on the proxy config service delegate object. 784 // Forward to a method on the proxy config service delegate object.
784 notify_delegate_->OnCheckProxyConfigSettings(); 785 notify_delegate_->OnCheckProxyConfigSettings();
785 } 786 }
786 787
787 void OnChangeNotification() { 788 void OnChangeNotification() {
788 // We don't use Reset() because the timer may not yet be running. 789 // We don't use Reset() because the timer may not yet be running.
789 // (In that case Stop() is a no-op.) 790 // (In that case Stop() is a no-op.)
790 debounce_timer_.Stop(); 791 debounce_timer_.Stop();
791 debounce_timer_.Start(FROM_HERE, 792 debounce_timer_.Start(FROM_HERE,
(...skipping 15 matching lines...) Expand all
807 GSettings* http_client_; 808 GSettings* http_client_;
808 GSettings* https_client_; 809 GSettings* https_client_;
809 GSettings* ftp_client_; 810 GSettings* ftp_client_;
810 GSettings* socks_client_; 811 GSettings* socks_client_;
811 ProxyConfigServiceLinux::Delegate* notify_delegate_; 812 ProxyConfigServiceLinux::Delegate* notify_delegate_;
812 base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_; 813 base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_;
813 814
814 // Message loop of the thread that we make gsettings calls on. It should 815 // Message loop of the thread that we make gsettings calls on. It should
815 // be the UI thread and all our methods should be called on this 816 // be the UI thread and all our methods should be called on this
816 // thread. Only for assertions. 817 // thread. Only for assertions.
817 MessageLoop* loop_; 818 scoped_refptr<base::MessageLoopProxy> loop_;
818 819
819 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); 820 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings);
820 }; 821 };
821 822
822 bool SettingGetterImplGSettings::LoadAndCheckVersion( 823 bool SettingGetterImplGSettings::LoadAndCheckVersion(
823 base::Environment* env) { 824 base::Environment* env) {
824 // LoadAndCheckVersion() must be called *before* Init()! 825 // LoadAndCheckVersion() must be called *before* Init()!
825 DCHECK(!client_); 826 DCHECK(!client_);
826 827
827 // The APIs to query gsettings were introduced after the minimum glib 828 // The APIs to query gsettings were introduced after the minimum glib
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 // on exiting the process, it may happen that Delegate::OnDestroy() 972 // on exiting the process, it may happen that Delegate::OnDestroy()
972 // task is left pending on the file loop after the loop was quit, 973 // task is left pending on the file loop after the loop was quit,
973 // and pending tasks may then be deleted without being run. 974 // and pending tasks may then be deleted without being run.
974 // Here in the KDE version, we can safely close the file descriptor 975 // Here in the KDE version, we can safely close the file descriptor
975 // anyway. (Not that it really matters; the process is exiting.) 976 // anyway. (Not that it really matters; the process is exiting.)
976 if (inotify_fd_ >= 0) 977 if (inotify_fd_ >= 0)
977 ShutDown(); 978 ShutDown();
978 DCHECK(inotify_fd_ < 0); 979 DCHECK(inotify_fd_ < 0);
979 } 980 }
980 981
981 virtual bool Init(MessageLoop* glib_default_loop, 982 virtual bool Init(base::MessageLoopProxy* glib_default_loop,
982 MessageLoopForIO* file_loop) OVERRIDE { 983 MessageLoopForIO* file_loop) OVERRIDE {
983 // This has to be called on the UI thread (http://crbug.com/69057). 984 // This has to be called on the UI thread (http://crbug.com/69057).
984 base::ThreadRestrictions::ScopedAllowIO allow_io; 985 base::ThreadRestrictions::ScopedAllowIO allow_io;
985 DCHECK(inotify_fd_ < 0); 986 DCHECK(inotify_fd_ < 0);
986 inotify_fd_ = inotify_init(); 987 inotify_fd_ = inotify_init();
987 if (inotify_fd_ < 0) { 988 if (inotify_fd_ < 0) {
988 PLOG(ERROR) << "inotify_init failed"; 989 PLOG(ERROR) << "inotify_init failed";
989 return false; 990 return false;
990 } 991 }
991 int flags = fcntl(inotify_fd_, F_GETFL); 992 int flags = fcntl(inotify_fd_, F_GETFL);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return false; 1025 return false;
1025 notify_delegate_ = delegate; 1026 notify_delegate_ = delegate;
1026 if (!file_loop_->WatchFileDescriptor(inotify_fd_, true, 1027 if (!file_loop_->WatchFileDescriptor(inotify_fd_, true,
1027 MessageLoopForIO::WATCH_READ, &inotify_watcher_, this)) 1028 MessageLoopForIO::WATCH_READ, &inotify_watcher_, this))
1028 return false; 1029 return false;
1029 // Simulate a change to avoid possibly losing updates before this point. 1030 // Simulate a change to avoid possibly losing updates before this point.
1030 OnChangeNotification(); 1031 OnChangeNotification();
1031 return true; 1032 return true;
1032 } 1033 }
1033 1034
1034 virtual MessageLoop* GetNotificationLoop() OVERRIDE { 1035 virtual base::MessageLoopProxy* GetNotificationLoop() OVERRIDE {
1035 return file_loop_; 1036 return file_loop_->message_loop_proxy();
1036 } 1037 }
1037 1038
1038 // Implement base::MessagePumpLibevent::Watcher. 1039 // Implement base::MessagePumpLibevent::Watcher.
1039 void OnFileCanReadWithoutBlocking(int fd) { 1040 void OnFileCanReadWithoutBlocking(int fd) {
1040 DCHECK_EQ(fd, inotify_fd_); 1041 DCHECK_EQ(fd, inotify_fd_);
1041 DCHECK(MessageLoop::current() == file_loop_); 1042 DCHECK(MessageLoop::current() == file_loop_);
1042 OnChangeNotification(); 1043 OnChangeNotification();
1043 } 1044 }
1044 void OnFileCanWriteWithoutBlocking(int fd) { 1045 void OnFileCanWriteWithoutBlocking(int fd) {
1045 NOTREACHED(); 1046 NOTREACHED();
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 } 1589 }
1589 } 1590 }
1590 1591
1591 ProxyConfigServiceLinux::Delegate::Delegate( 1592 ProxyConfigServiceLinux::Delegate::Delegate(
1592 base::Environment* env_var_getter, SettingGetter* setting_getter) 1593 base::Environment* env_var_getter, SettingGetter* setting_getter)
1593 : env_var_getter_(env_var_getter), setting_getter_(setting_getter), 1594 : env_var_getter_(env_var_getter), setting_getter_(setting_getter),
1594 glib_default_loop_(NULL), io_loop_(NULL) { 1595 glib_default_loop_(NULL), io_loop_(NULL) {
1595 } 1596 }
1596 1597
1597 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( 1598 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
1598 MessageLoop* glib_default_loop, MessageLoop* io_loop, 1599 base::MessageLoopProxy* glib_default_loop,
1600 base::MessageLoopProxy* io_loop,
1599 MessageLoopForIO* file_loop) { 1601 MessageLoopForIO* file_loop) {
1600 // We should be running on the default glib main loop thread right 1602 // We should be running on the default glib main loop thread right
1601 // now. gconf can only be accessed from this thread. 1603 // now. gconf can only be accessed from this thread.
1602 DCHECK(MessageLoop::current() == glib_default_loop); 1604 DCHECK(glib_default_loop->BelongsToCurrentThread());
1603 glib_default_loop_ = glib_default_loop; 1605 glib_default_loop_ = glib_default_loop;
1604 io_loop_ = io_loop; 1606 io_loop_ = io_loop;
1605 1607
1606 // If we are passed a NULL io_loop or file_loop, then we don't set up 1608 // If we are passed a NULL io_loop or file_loop, then we don't set up
1607 // proxy setting change notifications. This should not be the usual 1609 // proxy setting change notifications. This should not be the usual
1608 // case but is intended to simplify test setups. 1610 // case but is intended to simplify test setups.
1609 if (!io_loop_ || !file_loop) 1611 if (!io_loop_ || !file_loop)
1610 VLOG(1) << "Monitoring of proxy setting changes is disabled"; 1612 VLOG(1) << "Monitoring of proxy setting changes is disabled";
1611 1613
1612 // Fetch and cache the current proxy config. The config is left in 1614 // Fetch and cache the current proxy config. The config is left in
(...skipping 28 matching lines...) Expand all
1641 reference_config_.set_id(1); // Mark it as valid. 1643 reference_config_.set_id(1); // Mark it as valid.
1642 1644
1643 // We only set up notifications if we have IO and file loops available. 1645 // We only set up notifications if we have IO and file loops available.
1644 // We do this after getting the initial configuration so that we don't have 1646 // We do this after getting the initial configuration so that we don't have
1645 // to worry about cancelling it if the initial fetch above fails. Note that 1647 // to worry about cancelling it if the initial fetch above fails. Note that
1646 // setting up notifications has the side effect of simulating a change, so 1648 // setting up notifications has the side effect of simulating a change, so
1647 // that we won't lose any updates that may have happened after the initial 1649 // that we won't lose any updates that may have happened after the initial
1648 // fetch and before setting up notifications. We'll detect the common case 1650 // fetch and before setting up notifications. We'll detect the common case
1649 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. 1651 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it.
1650 if (io_loop && file_loop) { 1652 if (io_loop && file_loop) {
1651 MessageLoop* required_loop = setting_getter_->GetNotificationLoop(); 1653 scoped_refptr<base::MessageLoopProxy> required_loop =
1652 if (!required_loop || MessageLoop::current() == required_loop) { 1654 setting_getter_->GetNotificationLoop();
1655 if (!required_loop || required_loop->BelongsToCurrentThread()) {
1653 // In this case we are already on an acceptable thread. 1656 // In this case we are already on an acceptable thread.
1654 SetUpNotifications(); 1657 SetUpNotifications();
1655 } else { 1658 } else {
1656 // Post a task to set up notifications. We don't wait for success. 1659 // Post a task to set up notifications. We don't wait for success.
1657 required_loop->PostTask(FROM_HERE, base::Bind( 1660 required_loop->PostTask(FROM_HERE, base::Bind(
1658 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); 1661 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this));
1659 } 1662 }
1660 } 1663 }
1661 } 1664 }
1662 1665
1663 if (!got_config) { 1666 if (!got_config) {
1664 // We fall back on environment variables. 1667 // We fall back on environment variables.
1665 // 1668 //
1666 // Consulting environment variables doesn't need to be done from the 1669 // Consulting environment variables doesn't need to be done from the
1667 // default glib main loop, but it's a tiny enough amount of work. 1670 // default glib main loop, but it's a tiny enough amount of work.
1668 if (GetConfigFromEnv(&cached_config_)) { 1671 if (GetConfigFromEnv(&cached_config_)) {
1669 cached_config_.set_id(1); // Mark it as valid. 1672 cached_config_.set_id(1); // Mark it as valid.
1670 VLOG(1) << "Obtained proxy settings from environment variables"; 1673 VLOG(1) << "Obtained proxy settings from environment variables";
1671 } 1674 }
1672 } 1675 }
1673 } 1676 }
1674 1677
1675 // Depending on the SettingGetter in use, this method will be called 1678 // Depending on the SettingGetter in use, this method will be called
1676 // on either the UI thread (GConf) or the file thread (KDE). 1679 // on either the UI thread (GConf) or the file thread (KDE).
1677 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() { 1680 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() {
1678 MessageLoop* required_loop = setting_getter_->GetNotificationLoop(); 1681 scoped_refptr<base::MessageLoopProxy> required_loop =
1679 DCHECK(!required_loop || MessageLoop::current() == required_loop); 1682 setting_getter_->GetNotificationLoop();
1683 DCHECK(!required_loop || required_loop->BelongsToCurrentThread());
1680 if (!setting_getter_->SetUpNotifications(this)) 1684 if (!setting_getter_->SetUpNotifications(this))
1681 LOG(ERROR) << "Unable to set up proxy configuration change notifications"; 1685 LOG(ERROR) << "Unable to set up proxy configuration change notifications";
1682 } 1686 }
1683 1687
1684 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { 1688 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) {
1685 observers_.AddObserver(observer); 1689 observers_.AddObserver(observer);
1686 } 1690 }
1687 1691
1688 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { 1692 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) {
1689 observers_.RemoveObserver(observer); 1693 observers_.RemoveObserver(observer);
1690 } 1694 }
1691 1695
1692 ProxyConfigService::ConfigAvailability 1696 ProxyConfigService::ConfigAvailability
1693 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( 1697 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig(
1694 ProxyConfig* config) { 1698 ProxyConfig* config) {
1695 // This is called from the IO thread. 1699 // This is called from the IO thread.
1696 DCHECK(!io_loop_ || MessageLoop::current() == io_loop_); 1700 DCHECK(!io_loop_ || io_loop_->BelongsToCurrentThread());
1697 1701
1698 // Simply return the last proxy configuration that glib_default_loop 1702 // Simply return the last proxy configuration that glib_default_loop
1699 // notified us of. 1703 // notified us of.
1700 *config = cached_config_.is_valid() ? 1704 *config = cached_config_.is_valid() ?
1701 cached_config_ : ProxyConfig::CreateDirect(); 1705 cached_config_ : ProxyConfig::CreateDirect();
1702 1706
1703 // We return CONFIG_VALID to indicate that *config was filled in. It is always 1707 // We return CONFIG_VALID to indicate that *config was filled in. It is always
1704 // going to be available since we initialized eagerly on the UI thread. 1708 // going to be available since we initialized eagerly on the UI thread.
1705 // TODO(eroman): do lazy initialization instead, so we no longer need 1709 // TODO(eroman): do lazy initialization instead, so we no longer need
1706 // to construct ProxyConfigServiceLinux on the UI thread. 1710 // to construct ProxyConfigServiceLinux on the UI thread.
1707 // In which case, we may return false here. 1711 // In which case, we may return false here.
1708 return CONFIG_VALID; 1712 return CONFIG_VALID;
1709 } 1713 }
1710 1714
1711 // Depending on the SettingGetter in use, this method will be called 1715 // Depending on the SettingGetter in use, this method will be called
1712 // on either the UI thread (GConf) or the file thread (KDE). 1716 // on either the UI thread (GConf) or the file thread (KDE).
1713 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() { 1717 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() {
1714 MessageLoop* required_loop = setting_getter_->GetNotificationLoop(); 1718 scoped_refptr<base::MessageLoopProxy> required_loop =
1715 DCHECK(!required_loop || MessageLoop::current() == required_loop); 1719 setting_getter_->GetNotificationLoop();
1720 DCHECK(!required_loop || required_loop->BelongsToCurrentThread());
1716 ProxyConfig new_config; 1721 ProxyConfig new_config;
1717 bool valid = GetConfigFromSettings(&new_config); 1722 bool valid = GetConfigFromSettings(&new_config);
1718 if (valid) 1723 if (valid)
1719 new_config.set_id(1); // mark it as valid 1724 new_config.set_id(1); // mark it as valid
1720 1725
1721 // See if it is different from what we had before. 1726 // See if it is different from what we had before.
1722 if (new_config.is_valid() != reference_config_.is_valid() || 1727 if (new_config.is_valid() != reference_config_.is_valid() ||
1723 !new_config.Equals(reference_config_)) { 1728 !new_config.Equals(reference_config_)) {
1724 // Post a task to |io_loop| with the new configuration, so it can 1729 // Post a task to |io_loop| with the new configuration, so it can
1725 // update |cached_config_|. 1730 // update |cached_config_|.
1726 io_loop_->PostTask(FROM_HERE, base::Bind( 1731 io_loop_->PostTask(FROM_HERE, base::Bind(
1727 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, 1732 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig,
1728 this, new_config)); 1733 this, new_config));
1729 // Update the thread-private copy in |reference_config_| as well. 1734 // Update the thread-private copy in |reference_config_| as well.
1730 reference_config_ = new_config; 1735 reference_config_ = new_config;
1731 } else { 1736 } else {
1732 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; 1737 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing.";
1733 } 1738 }
1734 } 1739 }
1735 1740
1736 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( 1741 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig(
1737 const ProxyConfig& new_config) { 1742 const ProxyConfig& new_config) {
1738 DCHECK(MessageLoop::current() == io_loop_); 1743 DCHECK(io_loop_->BelongsToCurrentThread());
1739 VLOG(1) << "Proxy configuration changed"; 1744 VLOG(1) << "Proxy configuration changed";
1740 cached_config_ = new_config; 1745 cached_config_ = new_config;
1741 FOR_EACH_OBSERVER( 1746 FOR_EACH_OBSERVER(
1742 Observer, observers_, 1747 Observer, observers_,
1743 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID)); 1748 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID));
1744 } 1749 }
1745 1750
1746 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { 1751 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() {
1747 if (!setting_getter_.get()) 1752 if (!setting_getter_.get())
1748 return; 1753 return;
1749 MessageLoop* shutdown_loop = setting_getter_->GetNotificationLoop(); 1754 scoped_refptr<base::MessageLoopProxy> shutdown_loop =
1750 if (!shutdown_loop || MessageLoop::current() == shutdown_loop) { 1755 setting_getter_->GetNotificationLoop();
1756 if (!shutdown_loop || shutdown_loop->BelongsToCurrentThread()) {
1751 // Already on the right thread, call directly. 1757 // Already on the right thread, call directly.
1752 // This is the case for the unittests. 1758 // This is the case for the unittests.
1753 OnDestroy(); 1759 OnDestroy();
1754 } else { 1760 } else {
1755 // Post to shutdown thread. Note that on browser shutdown, we may quit 1761 // Post to shutdown thread. Note that on browser shutdown, we may quit
1756 // this MessageLoop and exit the program before ever running this. 1762 // this MessageLoop and exit the program before ever running this.
1757 shutdown_loop->PostTask(FROM_HERE, base::Bind( 1763 shutdown_loop->PostTask(FROM_HERE, base::Bind(
1758 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); 1764 &ProxyConfigServiceLinux::Delegate::OnDestroy, this));
1759 } 1765 }
1760 } 1766 }
1761 void ProxyConfigServiceLinux::Delegate::OnDestroy() { 1767 void ProxyConfigServiceLinux::Delegate::OnDestroy() {
1762 MessageLoop* shutdown_loop = setting_getter_->GetNotificationLoop(); 1768 scoped_refptr<base::MessageLoopProxy> shutdown_loop =
1763 DCHECK(!shutdown_loop || MessageLoop::current() == shutdown_loop); 1769 setting_getter_->GetNotificationLoop();
1770 DCHECK(!shutdown_loop || shutdown_loop->BelongsToCurrentThread());
1764 setting_getter_->ShutDown(); 1771 setting_getter_->ShutDown();
1765 } 1772 }
1766 1773
1767 ProxyConfigServiceLinux::ProxyConfigServiceLinux() 1774 ProxyConfigServiceLinux::ProxyConfigServiceLinux()
1768 : delegate_(new Delegate(base::Environment::Create())) { 1775 : delegate_(new Delegate(base::Environment::Create())) {
1769 } 1776 }
1770 1777
1771 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { 1778 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() {
1772 delegate_->PostDestroyTask(); 1779 delegate_->PostDestroyTask();
1773 } 1780 }
(...skipping 15 matching lines...) Expand all
1789 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { 1796 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) {
1790 delegate_->RemoveObserver(observer); 1797 delegate_->RemoveObserver(observer);
1791 } 1798 }
1792 1799
1793 ProxyConfigService::ConfigAvailability 1800 ProxyConfigService::ConfigAvailability
1794 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { 1801 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) {
1795 return delegate_->GetLatestProxyConfig(config); 1802 return delegate_->GetLatestProxyConfig(config);
1796 } 1803 }
1797 1804
1798 } // namespace net 1805 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/proxy_config_service_linux.h ('k') | net/proxy/proxy_config_service_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698