shill: Don't create DHCP and Modem D-Bus proxies in signal callbacks.
dbus-c++ doesn't allow proxy creation in signal callbacks so create them in
deferred tasks instead.
BUG=chromium-os:18228
TEST=unit tests, tested on device
Change-Id: I4f85ab937aef99ef4556c5a3c16af913d8fa08fd
Reviewed-on: http://gerrit.chromium.org/gerrit/4827
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
diff --git a/dhcp_config.cc b/dhcp_config.cc
index 8e9e7ff..e9661e0 100644
--- a/dhcp_config.cc
+++ b/dhcp_config.cc
@@ -16,6 +16,7 @@
#include "shill/glib.h"
#include "shill/ip_address.h"
#include "shill/proxy_factory.h"
+#include "shill/shill_event.h"
using std::string;
using std::vector;
@@ -44,6 +45,7 @@
DHCPConfig::DHCPConfig(ControlInterface *control_interface,
+ EventDispatcher *dispatcher,
DHCPProvider *provider,
const string &device_name,
GLib *glib)
@@ -52,6 +54,8 @@
pid_(0),
child_watch_tag_(0),
root_("/"),
+ task_factory_(this),
+ dispatcher_(dispatcher),
glib_(glib) {
store_.RegisterConstString(flimflam::kAddressProperty,
&(properties().address));
@@ -85,10 +89,6 @@
if (!pid_) {
return false;
}
- if (!proxy_.get()) {
- LOG(ERROR) << "Unable to renew IP before acquiring destination.";
- return false;
- }
proxy_->Rebind(device_name());
return true;
}
@@ -98,17 +98,25 @@
if (!pid_) {
return true;
}
- if (!proxy_.get()) {
- LOG(ERROR) << "Unable to release IP before acquiring destination.";
- return false;
+ if (proxy_.get()) {
+ proxy_->Release(device_name());
}
- proxy_->Release(device_name());
Stop();
return true;
}
-void DHCPConfig::InitProxy(const char *service) {
+void DHCPConfig::InitProxy(const string &service) {
+ // Defer proxy creation because dbus-c++ doesn't allow registration of new
+ // D-Bus objects in the context of a D-Bus signal handler.
if (!proxy_.get()) {
+ dispatcher_->PostTask(
+ task_factory_.NewRunnableMethod(&DHCPConfig::InitProxyTask, service));
+ }
+}
+
+void DHCPConfig::InitProxyTask(const string &service) {
+ if (!proxy_.get()) {
+ VLOG(2) << "Init DHCP Proxy: " << device_name() << " at " << service;
proxy_.reset(ProxyFactory::factory()->CreateDHCPProxy(service));
}
}