shill: Cache link status flags in DeviceInfo.
This allows the rest of the system to obtain current device flags at any given
point without going through RPC.
BUG=chromium-os:19027
TEST=unit tests
Change-Id: I8430f33bb1915115f1673944a1fb74fb8caefb1e
Reviewed-on: http://gerrit.chromium.org/gerrit/5762
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index ed7d630..d6a680b 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -17,7 +17,6 @@
#include <string>
#include <base/callback_old.h>
-#include <base/hash_tables.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <base/stl_util-inl.h>
@@ -35,7 +34,7 @@
#include "shill/service.h"
#include "shill/wifi.h"
-using base::hash_map;
+using std::map;
using std::string;
namespace shill {
@@ -82,8 +81,8 @@
void DeviceInfo::RegisterDevice(const DeviceRefPtr &device) {
VLOG(2) << __func__ << "(" << device->link_name() << ", "
<< device->interface_index() << ")";
- CHECK(!ContainsKey(devices_, device->interface_index()));
- devices_[device->interface_index()] = device;
+ CHECK(!GetDevice(device->interface_index()).get());
+ infos_[device->interface_index()].device = device;
if (device->TechnologyIs(Device::kCellular) ||
device->TechnologyIs(Device::kEthernet) ||
device->TechnologyIs(Device::kWifi)) {
@@ -91,14 +90,6 @@
}
}
-DeviceRefPtr DeviceInfo::GetDevice(int interface_index) {
- hash_map<int, DeviceRefPtr>::iterator iter = devices_.find(interface_index);
- if (iter == devices_.end()) {
- return NULL;
- }
- return iter->second;
-}
-
Device::Technology DeviceInfo::GetDeviceTechnology(const string &iface_name) {
char contents[1024];
int length;
@@ -150,7 +141,11 @@
int dev_index = msg.interface_index();
Device::Technology technology = Device::kUnknown;
- VLOG(2) << __func__;
+ unsigned int flags = msg.link_status().flags;
+ unsigned int change = msg.link_status().change;
+ VLOG(2) << __func__ << "(index=" << dev_index
+ << ", flags=" << flags << ", change=" << change << ")";
+ infos_[dev_index].flags = flags;
DeviceRefPtr device = GetDevice(dev_index);
if (!device.get()) {
@@ -191,22 +186,45 @@
}
RegisterDevice(device);
}
-
- device->LinkEvent(msg.link_status().flags, msg.link_status().change);
+ device->LinkEvent(flags, change);
}
void DeviceInfo::DelLinkMsgHandler(const RTNLMessage &msg) {
DCHECK(msg.type() == RTNLMessage::kMessageTypeLink &&
msg.mode() == RTNLMessage::kMessageModeDelete);
- RemoveDevice(msg.interface_index());
+ RemoveInfo(msg.interface_index());
}
-void DeviceInfo::RemoveDevice(int interface_index) {
- hash_map<int, DeviceRefPtr>::iterator ndev = devices_.find(interface_index);
- if (ndev != devices_.end()) {
- VLOG(2) << "Removing device index: " << interface_index;
- manager_->DeregisterDevice(ndev->second);
- devices_.erase(ndev);
+DeviceRefPtr DeviceInfo::GetDevice(int interface_index) {
+ Info *info = GetInfo(interface_index);
+ return info ? info->device : NULL;
+}
+
+bool DeviceInfo::GetFlags(int interface_index, unsigned int *flags) {
+ Info *info = GetInfo(interface_index);
+ if (!info) {
+ return false;
+ }
+ *flags = info->flags;
+ return true;
+}
+
+DeviceInfo::Info *DeviceInfo::GetInfo(int interface_index) {
+ map<int, Info>::iterator iter = infos_.find(interface_index);
+ if (iter == infos_.end()) {
+ return NULL;
+ }
+ return &iter->second;
+}
+
+void DeviceInfo::RemoveInfo(int interface_index) {
+ map<int, Info>::iterator iter = infos_.find(interface_index);
+ if (iter != infos_.end()) {
+ VLOG(2) << "Removing info for device index: " << interface_index;
+ if (iter->second.device.get()) {
+ manager_->DeregisterDevice(iter->second.device);
+ }
+ infos_.erase(iter);
}
}