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

Side by Side Diff: src/service.cc

Issue 5284004: Revert "cashew: do not delete DBus::ObjectProxy objects from D-Bus callbacks" (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/cashew.git@master
Patch Set: Created 10 years, 1 month 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
« no previous file with comments | « src/service.h ('k') | src/service_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 "src/service.h" 5 #include "src/service.h"
6 6
7 #include <glog/logging.h> 7 #include <glog/logging.h>
8 8
9 #include "src/data_plan_provider.h" 9 #include "src/data_plan_provider.h"
10 #include "src/device.h" 10 #include "src/device.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 Service::Service(ServiceManager * const parent, 76 Service::Service(ServiceManager * const parent,
77 DBus::Connection& connection, // NOLINT 77 DBus::Connection& connection, // NOLINT
78 const DBus::Path& path) 78 const DBus::Path& path)
79 : DBus::ObjectProxy(connection, path, kFlimflamServiceName), 79 : DBus::ObjectProxy(connection, path, kFlimflamServiceName),
80 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path), 80 parent_(CHECK_NOTNULL(parent)), connection_(connection), path_(path),
81 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL), 81 state_(kStateUnknown), type_(kTypeUnknown), device_(NULL),
82 provider_(NULL), request_in_progress_(false), 82 provider_(NULL), request_in_progress_(false),
83 update_timeout_source_(NULL), policy_(NULL), 83 update_timeout_source_(NULL), policy_(NULL),
84 is_default_service_(false), get_properties_source_id_(0), 84 is_default_service_(false), get_properties_source_id_(0),
85 retrying_get_properties_(false), 85 retrying_get_properties_(false),
86 connectivity_state_(kConnectivityStateUnknown), 86 connectivity_state_(kConnectivityStateUnknown) {
87 deferred_device_deletion_source_id_(0) {
88 // schedule a GetProperties() call to our Flimflam service path to init state 87 // schedule a GetProperties() call to our Flimflam service path to init state
89 // we'll keep trying periodically until we succeed 88 // we'll keep trying periodically until we succeed
90 // we'll subsequently update this state by monitoring PropertyChanged signals 89 // we'll subsequently update this state by monitoring PropertyChanged signals
91 get_properties_source_id_ = 90 get_properties_source_id_ =
92 g_idle_add(StaticGetServicePropertiesCallback, this); 91 g_idle_add(StaticGetServicePropertiesCallback, this);
93 if (get_properties_source_id_ == 0) { 92 if (get_properties_source_id_ == 0) {
94 LOG(ERROR) << path_ << ": ctor: g_idle_add failed"; 93 LOG(ERROR) << path_ << ": ctor: g_idle_add failed";
95 } 94 }
96 } 95 }
97 96
98 Service::~Service() { 97 Service::~Service() {
99 DeleteCarrierState(); 98 DeleteCarrierState();
100 DeleteDataPlans(&data_plans_); 99 DeleteDataPlans(&data_plans_);
101 // ServiceManager ensures that this dtor is not being called from within a
102 // D-Bus callback, so it's ok to delete |device_| and any members of
103 // |devices_pending_deletion_| directly.
104 if (device_ != NULL) { 100 if (device_ != NULL) {
105 DLOG(INFO) << path_ << ": dtor: deleting device " << device_->GetPath(); 101 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath();
106 delete device_; 102 delete device_;
107 device_ = NULL; 103 device_ = NULL;
108 } 104 }
109 DeletePendingDevices();
110 if (get_properties_source_id_ != 0 && 105 if (get_properties_source_id_ != 0 &&
111 !g_source_remove(get_properties_source_id_)) { 106 !g_source_remove(get_properties_source_id_)) {
112 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed for source id " 107 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed";
113 << get_properties_source_id_;
114 }
115 if (deferred_device_deletion_source_id_ != 0 &&
116 !g_source_remove(deferred_device_deletion_source_id_)) {
117 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed for source id "
118 << deferred_device_deletion_source_id_;
119 } 108 }
120 } 109 }
121 110
122 const DBus::Path& Service::GetPath() const { 111 const DBus::Path& Service::GetPath() const {
123 return path_; 112 return path_;
124 } 113 }
125 114
126 Service::State Service::GetState() const { 115 Service::State Service::GetState() const {
127 return state_; 116 return state_;
128 } 117 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 } 443 }
455 444
456 bool Service::RetryingGetProperties() const { 445 bool Service::RetryingGetProperties() const {
457 return retrying_get_properties_; 446 return retrying_get_properties_;
458 } 447 }
459 448
460 void Service::OnRetryingGetProperties(bool retrying) { 449 void Service::OnRetryingGetProperties(bool retrying) {
461 retrying_get_properties_ = retrying; 450 retrying_get_properties_ = retrying;
462 } 451 }
463 452
464 guint Service::GetDeferredDeviceDeletionSourceId() const {
465 return deferred_device_deletion_source_id_;
466 }
467
468 void Service::SetDeferredDeviceDeletionSourceId(guint source_id) {
469 deferred_device_deletion_source_id_ = source_id;
470 }
471
472 // Private methods 453 // Private methods
473 454
474 void Service::DeletePendingDevices() {
475 while (!devices_pending_deletion_.empty()) {
476 Device *device = *(devices_pending_deletion_.begin());
477 DCHECK(device != NULL);
478 DLOG(INFO) << path_ << ": DeletePendingDevices: deleting device: "
479 << device->GetPath();
480 DCHECK(device != device_);
481 delete device;
482 devices_pending_deletion_.erase(devices_pending_deletion_.begin());
483 }
484 }
485
486 void Service::ScheduleDeviceForLaterDeletion(Device *device) {
487 DCHECK(device != NULL);
488 DCHECK(device != device_);
489 // We might be inside of a D-Bus callback. We add the device to our
490 // |devices_pending_deletion_| list and schedule a glib callback to
491 // delete these devices from the main loop if one is not already
492 // scheduled.
493 DLOG(INFO) << path_ << ": ScheduleDeviceForLaterDeletion: "
494 << device->GetPath();
495 devices_pending_deletion_.push_back(device);
496 if (deferred_device_deletion_source_id_ != 0) {
497 DLOG(INFO) << path_ << ": ScheduleDeviceForLaterDeletion: "
498 << "deferred device deletion callback already scheduled";
499 return;
500 }
501 deferred_device_deletion_source_id_ =
502 g_idle_add(StaticDeletePendingDevicesCallback, this);
503 if (deferred_device_deletion_source_id_ == 0) {
504 LOG(ERROR) << path_
505 << ": ScheduleDeviceForLaterDeletion: g_idle_add failed";
506 return;
507 }
508 DLOG(INFO) << path_ << ": ScheduleDeviceForLaterDeletion: "
509 << "scheduled deferred device deletion callback";
510 }
511
512 // static
513 gboolean Service::StaticDeletePendingDevicesCallback(gpointer data) {
514 Service *service = reinterpret_cast<Service*>(data);
515 DCHECK(service != NULL);
516 DCHECK_NE(service->GetDeferredDeviceDeletionSourceId(), 0);
517 service->DeletePendingDevices();
518 // we don't want to be run again automatically
519 // ScheduleDeviceForLaterDeletion will schedule us as needed
520 service->SetDeferredDeviceDeletionSourceId(0);
521 return FALSE;
522 }
523
524 // static 455 // static
525 Service::ConnectivityState Service::ConnectivityStateFromString( 456 Service::ConnectivityState Service::ConnectivityStateFromString(
526 const std::string& connectivity_state) { 457 const std::string& connectivity_state) {
527 if (connectivity_state == kFlimflamServiceConnectivityStateUnknown) { 458 if (connectivity_state == kFlimflamServiceConnectivityStateUnknown) {
528 return kConnectivityStateUnknown; 459 return kConnectivityStateUnknown;
529 } 460 }
530 if (connectivity_state == kFlimflamServiceConnectivityStateRestricted) { 461 if (connectivity_state == kFlimflamServiceConnectivityStateRestricted) {
531 return kConnectivityStateRestricted; 462 return kConnectivityStateRestricted;
532 } 463 }
533 if (connectivity_state == kFlimflamServiceConnectivityStateUnrestricted) { 464 if (connectivity_state == kFlimflamServiceConnectivityStateUnrestricted) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 } 500 }
570 501
571 void Service::OnDeviceUpdate(const DBus::Path& device_path) { 502 void Service::OnDeviceUpdate(const DBus::Path& device_path) {
572 DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path; 503 DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path;
573 504
574 // if there's an existing device with a non-matching path: destroy it and 505 // if there's an existing device with a non-matching path: destroy it and
575 // fall through to make a new one below. 506 // fall through to make a new one below.
576 if (device_ != NULL && device_->GetPath() != device_path) { 507 if (device_ != NULL && device_->GetPath() != device_path) {
577 LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from " 508 LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from "
578 << device_->GetPath() << " to " << device_path; 509 << device_->GetPath() << " to " << device_path;
579 // We might be in a D-Bus callback, so schedule device for later deletion 510 delete device_;
580 // to avoid possible deadlock. See the comments in service_manager.h and
581 // service_manager.cc for more on this issue.
582 Device *device_to_delete = device_;
583 device_ = NULL; 511 device_ = NULL;
584 ScheduleDeviceForLaterDeletion(device_to_delete);
585 } 512 }
586 513
587 // if there's an existing device with matching path: all is well 514 // if there's an existing device with matching path: all is well
588 if (device_ != NULL) { 515 if (device_ != NULL) {
589 return; 516 return;
590 } 517 }
591 518
592 // if there's no existing device: make one 519 // if there's no existing device: make one
593 device_ = new(std::nothrow) Device(this, connection_, device_path); 520 device_ = new(std::nothrow) Device(this, connection_, device_path);
594 if (device_ == NULL) { 521 if (device_ == NULL) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 DCHECK(policy_ != NULL); 915 DCHECK(policy_ != NULL);
989 if (policy_->ShouldEmitDataPlansUpdate(data_plans_)) { 916 if (policy_->ShouldEmitDataPlansUpdate(data_plans_)) {
990 DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: sending update"; 917 DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: sending update";
991 parent_->EmitDataPlansUpdate(*this); 918 parent_->EmitDataPlansUpdate(*this);
992 } else { 919 } else {
993 DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: not sending update"; 920 DLOG(INFO) << path_ << ": MaybeEmitDataPlansUpdate: not sending update";
994 } 921 }
995 } 922 }
996 923
997 } // namespace cashew 924 } // namespace cashew
OLDNEW
« no previous file with comments | « src/service.h ('k') | src/service_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698