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

Unified Diff: src/service.cc

Issue 4304002: cashew: don't invoke D-Bus methods from within a D-Bus handler (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/service.h ('k') | src/service_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/service.cc
diff --git a/src/service.cc b/src/service.cc
index 210609c72d9e72aefedd539c62d641ad775ef5bc..3d0f808257afa542c53cbaddb3e2c124d622e08f 100644
--- a/src/service.cc
+++ b/src/service.cc
@@ -60,6 +60,10 @@ static const char *kCrosUsageStatusServiceUnavailable = "SERVICE UNAVAILABLE";
static const char *kCrosUsageStatusRequestRefused = "REQUEST REFUSED";
static const char *kCrosUsageStatusUnknownDevice = "UNKNOWN DEVICE";
+// GetServiceProperties retry interval
+static const guint kSecondsPerMinute = 60;
+static const guint kGetServicePropertiesIntervalSeconds = 1 * kSecondsPerMinute;
+
Service::Service(ServiceManager * const parent,
DBus::Connection& connection, // NOLINT
const DBus::Path& path)
@@ -68,10 +72,16 @@ Service::Service(ServiceManager * const parent,
state_(kStateUnknown), type_(kTypeUnknown), device_(NULL),
provider_(NULL), request_in_progress_(false),
update_timeout_source_(NULL), policy_(NULL),
- is_default_service_(false) {
- // init our state with a GetProperties() call to our Flimflam service path
- // we'll update this state by monitoring PropertyChanged signals
- GetServiceProperties();
+ is_default_service_(false), get_properties_source_id_(0),
+ retrying_get_properties_(false) {
+ // schedule a GetProperties() call to our Flimflam service path to init state
+ // we'll keep trying periodically until we succeed
+ // we'll subsequently update this state by monitoring PropertyChanged signals
+ get_properties_source_id_ =
+ g_idle_add(StaticGetServicePropertiesCallback, this);
+ if (get_properties_source_id_ == 0) {
+ LOG(ERROR) << path_ << ": ctor: g_idle_add failed";
+ }
}
Service::~Service() {
@@ -82,6 +92,10 @@ Service::~Service() {
delete device_;
device_ = NULL;
}
+ if (get_properties_source_id_ != 0 &&
+ !g_source_remove(get_properties_source_id_)) {
+ DLOG(WARNING) << path_ << ": dtor: g_source_remove failed";
+ }
}
const DBus::Path& Service::GetPath() const {
@@ -348,6 +362,24 @@ void Service::OnFlimflamOffline() {
ReconsiderSendingUsageRequests();
}
+// glib integration interface
+
+guint Service::GetGetPropertiesSourceId() const {
+ return get_properties_source_id_;
+}
+
+void Service::SetGetPropertiesSourceId(guint source_id) {
+ get_properties_source_id_ = source_id;
+}
+
+bool Service::RetryingGetProperties() const {
+ return retrying_get_properties_;
+}
+
+void Service::OnRetryingGetProperties(bool retrying) {
+ retrying_get_properties_ = retrying;
+}
+
// Private methods
Service::State Service::StateFromString(const std::string& state) const {
@@ -439,7 +471,43 @@ void Service::OnUsageUrlUpdate(const std::string& usage_url) {
}
}
-void Service::GetServiceProperties() {
+// static
+gboolean Service::StaticGetServicePropertiesCallback(gpointer data) {
+ Service *service = reinterpret_cast<Service*>(data);
+ CHECK_NOTNULL(service);
+ DCHECK_NE(service->GetGetPropertiesSourceId(), 0);
+ if (!service->GetServiceProperties()) {
+ // call failed, so try again later
+ DLOG(WARNING) << service->GetPath()
+ << ": StaticGetServicePropertiesCallback: "
+ << "GetServiceProperties failed, will retry in "
+ << kGetServicePropertiesIntervalSeconds << " secs";
+ // if we've arrived here from our first g_idle_add call, set up a timer
+ if (!service->RetryingGetProperties()) {
+ guint source_id =
+ g_timeout_add_seconds(kGetServicePropertiesIntervalSeconds,
+ StaticGetServicePropertiesCallback, service);
+ service->SetGetPropertiesSourceId(source_id);
+ if (source_id == 0) {
+ LOG(ERROR) << service->GetPath()
+ << ": StaticGetServicePropertiesCallback: "
+ << "g_timeout_add_seconds failed";
+ return FALSE; // get rid of old glib source and give up
+ }
+ service->OnRetryingGetProperties(true);
+ // get rid of our old glib source, but our new timer will call us
+ return FALSE;
+ }
+ // otherwise, our timer is already set up
+ // return TRUE to indicate that we want to be called again later
+ return TRUE;
+ }
+ service->SetGetPropertiesSourceId(0);
+ service->OnRetryingGetProperties(false);
+ return FALSE; // we succeeded, so don't repeat
+}
+
+bool Service::GetServiceProperties() {
DLOG(INFO) << path_ << ": GetServiceProperties";
PropertyMap properties;
// dbus-c++ throws exceptions
@@ -452,13 +520,11 @@ void Service::GetServiceProperties() {
LOG(WARNING) << path_
<< ": GetServiceProperties: GetProperties() -> Exception: "
<< error.name() << ": " << error.message();
- // TODO(vlaviano): schedule another attempt later
- return;
+ return false;
} catch (...) { // NOLINT
LOG(WARNING) << path_
<< ": GetServiceProperties: GetProperties() -> Exception";
- // TODO(vlaviano): schedule another attempt later
- return;
+ return false;
}
DLOG(INFO) << path_ << ": GetServiceProperties: Received "
<< properties.size() << " properties";
@@ -488,7 +554,7 @@ void Service::GetServiceProperties() {
}
// don't expect to find Cellular.* properties if we're not a cellular service
if (type_ != kTypeCellular) {
- return;
+ return true;
}
it = properties.find(kFlimflamServiceUsageUrlProperty);
if (it != properties.end()) {
@@ -498,6 +564,7 @@ void Service::GetServiceProperties() {
DLOG(WARNING) << path_
<< ": GetServiceProperties: no Cellular.UsageUrl property";
}
+ return true;
}
void Service::DeleteDataPlans(DataPlanList *data_plans) {
@@ -564,8 +631,9 @@ gboolean Service::UpdateTimeoutCallback() {
// static
gboolean Service::StaticUpdateTimeoutCallback(gpointer data) {
- CHECK_NOTNULL(data);
- return reinterpret_cast<Service*>(data)->UpdateTimeoutCallback();
+ Service *service = reinterpret_cast<Service*>(data);
+ CHECK_NOTNULL(service);
+ return service->UpdateTimeoutCallback();
}
bool Service::CreateUpdateTimer() {
« 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