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

Unified Diff: src/service_manager.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_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/service_manager.cc
diff --git a/src/service_manager.cc b/src/service_manager.cc
index 23041b942618f525582f3b5ddcadffc1c716de27..2e8a9649646a6b6205df5efae631095918fd28a9 100644
--- a/src/service_manager.cc
+++ b/src/service_manager.cc
@@ -28,21 +28,36 @@ static const char *kFlimflamStateOnline = "online";
// Flimflam service types
static const char *kTypeCellular = "cellular";
+// GetFlimflamProperties retry interval
+static const guint kSecondsPerMinute = 60;
+static const guint kGetFlimflamPropertiesIntervalSeconds =
+ 1 * kSecondsPerMinute;
+
ServiceManager::ServiceManager(DBus::Connection& connection) // NOLINT
: DBus::ObjectProxy(connection, kFlimflamManagerPath,
kFlimflamManagerName),
connection_(connection), cashew_server_(NULL),
default_technology_(Service::kTypeUnknown),
default_cellular_service_(NULL),
- connectivity_state_(kConnectivityStateUnknown) {
- // init our state with a GetProperties() call to Flimflam
- // we'll update this state by monitoring PropertyChanged signals
- GetFlimflamProperties();
+ connectivity_state_(kConnectivityStateUnknown),
+ get_properties_source_id_(0), retrying_get_properties_(false) {
+ // schedule a GetProperties() call to Flimflam to init our 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(StaticGetFlimflamPropertiesCallback, this);
+ if (get_properties_source_id_ == 0) {
+ LOG(ERROR) << "ctor: g_idle_add failed";
+ }
}
ServiceManager::~ServiceManager() {
ClearDefaultCellularService();
DeleteServices(&services_);
+ if (get_properties_source_id_ != 0 &&
+ !g_source_remove(get_properties_source_id_)) {
+ DLOG(WARNING) << "dtor: g_source_remove failed";
+ }
}
const Service* ServiceManager::GetService(const std::string& service_path)
@@ -136,6 +151,24 @@ void ServiceManager::EmitDataPlansUpdate(const Service& service) {
cashew_server_->EmitDataPlansUpdate(service);
}
+// glib integration interface
+
+guint ServiceManager::GetGetPropertiesSourceId() const {
+ return get_properties_source_id_;
+}
+
+void ServiceManager::SetGetPropertiesSourceId(guint source_id) {
+ get_properties_source_id_ = source_id;
+}
+
+bool ServiceManager::RetryingGetProperties() const {
+ return retrying_get_properties_;
+}
+
+void ServiceManager::OnRetryingGetProperties(bool retrying) {
+ retrying_get_properties_ = retrying;
+}
+
// Private methods
void ServiceManager::DeleteServices(ServiceMap *service_map) {
@@ -153,7 +186,42 @@ void ServiceManager::DeleteServices(ServiceMap *service_map) {
}
}
-void ServiceManager::GetFlimflamProperties() {
+// static
+gboolean ServiceManager::StaticGetFlimflamPropertiesCallback(gpointer data) {
+ ServiceManager *service_manager = reinterpret_cast<ServiceManager*>(data);
+ CHECK_NOTNULL(service_manager);
+ DCHECK_NE(service_manager->GetGetPropertiesSourceId(), 0);
+ if (!service_manager->GetFlimflamProperties()) {
+ // call failed, so try again later
+ DLOG(WARNING) << "StaticGetFlimflamPropertiesCallback: "
+ << "GetFlimflamProperties failed, will retry in "
+ << kGetFlimflamPropertiesIntervalSeconds << " secs";
+ // if we've arrived here from our first g_idle_add call, set up a timer
+ if (!service_manager->RetryingGetProperties()) {
+ guint source_id =
+ g_timeout_add_seconds(kGetFlimflamPropertiesIntervalSeconds,
+ StaticGetFlimflamPropertiesCallback,
+ service_manager);
+ service_manager->SetGetPropertiesSourceId(source_id);
+ if (source_id == 0) {
+ LOG(ERROR) << "StaticGetFlimflamPropertiesCallback: "
+ << "g_timeout_add_seconds failed";
+ return FALSE; // get rid of old glib source and give up
+ }
+ service_manager->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_manager->SetGetPropertiesSourceId(0);
+ service_manager->OnRetryingGetProperties(false);
+ return FALSE; // we succeeded, so don't repeat
+}
+
+bool ServiceManager::GetFlimflamProperties() {
DLOG(INFO) << "GetFlimflamProperties";
PropertyMap properties;
// dbus-c++ throws exceptions
@@ -165,12 +233,10 @@ void ServiceManager::GetFlimflamProperties() {
} catch (DBus::Error& error) { // NOLINT
LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception: "
<< error.name() << ": " << error.message();
- // TODO(vlaviano): schedule another attempt later
- return;
+ return false;
} catch (...) { // NOLINT
LOG(WARNING) << "GetFlimflamProperties: GetProperties() -> Exception";
- // TODO(vlaviano): schedule another attempt later
- return;
+ return false;
}
DLOG(INFO) << "GetFlimflamProperties: Received " << properties.size()
<< " properties";
@@ -201,6 +267,7 @@ void ServiceManager::GetFlimflamProperties() {
} else {
DLOG(WARNING) << "GetFlimflamProperties: no State property";
}
+ return true;
}
void ServiceManager::OnDefaultTechnologyUpdate(
« no previous file with comments | « src/service_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698