shill: wimax: Support WiMaxService::Unload.
On Unload, deregister and destroy all non-default services. Also, when a default
service is stopped (because its network has disappeared), deregister it from
Manager and destroy it -- this makes StartLiveServices symmetrical to
StopDeadServices.
BUG=chrome-os-partner:9942
TEST=unit tests
Change-Id: Ie9598b21529cbaf7a6b195468cbbd1e10edbe076
Reviewed-on: https://gerrit.chromium.org/gerrit/23649
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/wimax_provider.cc b/wimax_provider.cc
index 1091e74..94a98f0 100644
--- a/wimax_provider.cc
+++ b/wimax_provider.cc
@@ -27,7 +27,6 @@
using std::map;
using std::set;
using std::string;
-using std::vector;
namespace shill {
@@ -65,7 +64,8 @@
void WiMaxProvider::OnDeviceInfoAvailable(const string &link_name) {
SLOG(WiMax, 2) << __func__ << "(" << link_name << ")";
- map<string, string>::iterator find_it = pending_devices_.find(link_name);
+ map<string, RpcIdentifier>::iterator find_it =
+ pending_devices_.find(link_name);
if (find_it != pending_devices_.end()) {
RpcIdentifier path = find_it->second;
CreateDevice(link_name, path);
@@ -87,6 +87,17 @@
StartLiveServices();
}
+bool WiMaxProvider::OnServiceUnloaded(const WiMaxServiceRefPtr &service) {
+ SLOG(WiMax, 2) << __func__ << "(" << service->GetStorageIdentifier() << ")";
+ if (service->is_default()) {
+ return false;
+ }
+ // Removes the service from the managed service set. The service will be
+ // deregistered from Manager when we release ownership by returning true.
+ services_.erase(service->GetStorageIdentifier());
+ return true;
+}
+
WiMaxServiceRefPtr WiMaxProvider::GetService(const KeyValueStore &args,
Error *error) {
SLOG(WiMax, 2) << __func__;
@@ -214,7 +225,7 @@
void WiMaxProvider::DestroyDeadDevices(const RpcIdentifiers &live_devices) {
SLOG(WiMax, 2) << __func__ << "(" << live_devices.size() << ")";
- for (map<string, string>::iterator it = pending_devices_.begin();
+ for (map<string, RpcIdentifier>::iterator it = pending_devices_.begin();
it != pending_devices_.end(); ) {
if (find(live_devices.begin(), live_devices.end(), it->second) ==
live_devices.end()) {
@@ -247,13 +258,14 @@
WiMaxServiceRefPtr WiMaxProvider::FindService(const string &storage_id) {
SLOG(WiMax, 2) << __func__ << "(" << storage_id << ")";
- for (vector<WiMaxServiceRefPtr>::const_iterator it = services_.begin();
- it != services_.end(); ++it) {
- if ((*it)->GetStorageIdentifier() == storage_id) {
- return *it;
- }
+ map<string, WiMaxServiceRefPtr>::const_iterator find_it =
+ services_.find(storage_id);
+ if (find_it == services_.end()) {
+ return NULL;
}
- return NULL;
+ const WiMaxServiceRefPtr &service = find_it->second;
+ LOG_IF(ERROR, storage_id != service->GetStorageIdentifier());
+ return service;
}
WiMaxServiceRefPtr WiMaxProvider::GetUniqueService(const WiMaxNetworkId &id,
@@ -269,7 +281,7 @@
service->set_network_id(id);
service->set_friendly_name(name);
service->InitStorageIdentifier();
- services_.push_back(service);
+ services_[service->GetStorageIdentifier()] = service;
manager_->RegisterService(service);
LOG(INFO) << "Registered WiMAX service: " << service->GetStorageIdentifier();
return service;
@@ -289,8 +301,12 @@
if (error.IsFailure()) {
return NULL;
}
- return GetUniqueService(
- WiMaxService::ConvertIdentifierToNetworkId(identifier), name);
+ WiMaxServiceRefPtr service =
+ GetUniqueService(
+ WiMaxService::ConvertIdentifierToNetworkId(identifier), name);
+ CHECK(service);
+ service->set_is_default(true);
+ return service;
}
void WiMaxProvider::StartLiveServices() {
@@ -307,9 +323,9 @@
return;
}
// Start services for this live network identifier.
- for (vector<WiMaxServiceRefPtr>::iterator it = services_.begin();
+ for (map<string, WiMaxServiceRefPtr>::const_iterator it = services_.begin();
it != services_.end(); ++it) {
- const WiMaxServiceRefPtr &service = *it;
+ const WiMaxServiceRefPtr &service = it->second;
if (service->network_id() != default_service->network_id() ||
service->IsStarted()) {
continue;
@@ -323,27 +339,35 @@
void WiMaxProvider::StopDeadServices() {
SLOG(WiMax, 2) << __func__ << "(" << networks_.size() << ")";
- for (vector<WiMaxServiceRefPtr>::iterator it = services_.begin();
- it != services_.end(); ++it) {
- const WiMaxServiceRefPtr &service = *it;
- if (!service->IsStarted() ||
- ContainsKey(networks_, service->GetNetworkObjectPath())) {
- continue;
+ for (map<string, WiMaxServiceRefPtr>::iterator it = services_.begin();
+ it != services_.end(); ) {
+ const WiMaxServiceRefPtr &service = it->second;
+ if (service->IsStarted() &&
+ !ContainsKey(networks_, service->GetNetworkObjectPath())) {
+ service->Stop();
+ // Default services are created and registered when a network becomes
+ // live. They need to be deregistered and destroyed when the network
+ // disappears.
+ if (service->is_default()) {
+ manager_->DeregisterService(service);
+ services_.erase(it++);
+ continue;
+ }
}
- service->Stop();
+ ++it;
}
}
void WiMaxProvider::DestroyAllServices() {
SLOG(WiMax, 2) << __func__;
- while (!services_.empty()) {
- const WiMaxServiceRefPtr &service = services_.back();
+ for (map<string, WiMaxServiceRefPtr>::iterator it = services_.begin();
+ it != services_.end(); services_.erase(it++)) {
+ const WiMaxServiceRefPtr &service = it->second;
// Stop the service so that it can notify its carrier device, if any.
service->Stop();
manager_->DeregisterService(service);
LOG(INFO) << "Deregistered WiMAX service: "
<< service->GetStorageIdentifier();
- services_.pop_back();
}
}