Commit 4a464098d54e54d5e2608d140905941791354d47

  • avatar
  • swiesner <swiesner @283d02a7-25f6-0310…ecb5cbfe19da.>
  • Thu Aug 05 13:28:07 CEST 2010
Cache serial and product name lookups to decrease amount of udev queries

git-svn-id: svn+ssh://svn.kde.org/home/kde/trunk/playground/utils/synaptiks@1159455 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
  
5151
5252 QUDevDevicePtr findDeviceBySerial(const QByteArray &serial) const;
5353
54 QSet<QString> mouseDevices;
54 // maps serials to device paths to speed up mapping from serial
55 // numbers to device paths
56 mutable QHash<QByteArray, QByteArray> serialCache;
57 // map serials to product names to speed up
58 mutable QHash<QByteArray, QByteArray> productNameCache;
5559 QUDevContextPtr context;
5660 QUDevMonitorPtr monitor;
5761 QSocketNotifier *monitorNotifier;
109109 QByteArray serial = getSerial(device);
110110 if (action == "add") {
111111 kDebug() << "mouse added:" << serial;
112 QByteArray sysPath = udev_device_get_syspath(device);
113 this->serialCache.insert(serial, sysPath);
112114 emit q->mousePlugged(QString::fromAscii(serial));
113115 } else if (action == "remove") {
114116 kDebug() << "mouse removed:" << serial;
117 // remove device from all caches
118 this->serialCache.remove(serial);
119 this->productNameCache.remove(serial);
115120 emit q->mouseUnplugged(QString::fromAscii(serial));
116121 }
117122 }
125125QUDevDevicePtr MouseDevicesMonitorPrivate::findDeviceBySerial(
126126 const QByteArray &serial) const {
127127 kDebug() << "searching device for serial" << serial;
128 QUDevDevicePtr device;
128 // try to get the device from cache
129 QByteArray sysPath = this->serialCache.value(serial);
130 if (!sysPath.isEmpty()) {
131 QUDevDevicePtr device =
132 udev_device_new_from_syspath(this->context, sysPath);
133 if (device && isMouse(device)) {
134 kDebug() << "found device for serial" << serial << "in cache";
135 return device;
136 }
137 }
138 // cache miss, query udev for a device with the given serial number
129139 QUDevEnumeratePtr enumerator = udev_enumerate_new(this->context);
130140 Q_ASSERT(enumerator);
131141 // filter for the given serial number
147147 udev_enumerate_get_list_entry(enumerator);
148148 udev_list_entry *current_entry = 0;
149149 udev_list_entry_foreach(current_entry, device_entries) {
150 device = udev_device_new_from_syspath(
151 this->context, udev_list_entry_get_name(current_entry));
150 QByteArray sysPath = udev_list_entry_get_name(current_entry);
151 QUDevDevicePtr device = udev_device_new_from_syspath(
152 this->context, sysPath);
152153 // we have a matching mouse device
153154 if (device && isMouse(device)) {
154155 kDebug() << "found device for serial:" << serial;
155 break;
156 // cache the result of the udev query
157 this->serialCache.insert(serial, sysPath);
158 return device;
156159 }
157160 }
158 return device;
161 return 0;
159162}
160163
161164MouseDevicesMonitor::MouseDevicesMonitor(QObject *parent):
185185 udev_list_entry_foreach(current_entry, device_entries) {
186186 QUDevDevicePtr device = udev_device_new_from_syspath(
187187 d->context, udev_list_entry_get_name(current_entry));
188 // a true mouse device
188 // a real mouse device
189189 if (device && isMouse(device)) {
190190 QByteArray serial = getSerial(device);
191 kDebug() << "found device with serial" << serial;
191 // update the serial cache
192 QByteArray sysPath = udev_device_get_syspath(device);
193 d->serialCache.insert(serial, sysPath);
194 kDebug() << "device with serial" << serial;
192195 devices << QString::fromAscii(serial);
193196 }
194197 }
201201QString MouseDevicesMonitor::productName(const QString &id) const {
202202 Q_D(const MouseDevicesMonitor);
203203 kDebug() << "querying product name for serial" << id;
204 QString name;
204 QByteArray serial = id.toAscii();
205 // try to get product name from cache
206 QByteArray name = d->productNameCache.value(serial);
207 if (!name.isEmpty()) {
208 kDebug() << "found product name" << name
209 << "for serial" << serial << "in cache";
210 return QString::fromAscii(name);
211 }
212 // cache miss, query udev for the product name
205213 QUDevDevicePtr device = d->findDeviceBySerial(id.toAscii());
206214 if (device) {
207215 // no need for a guarded pointer here, the parent device is freed
208216 // together with the child
209217 udev_device *parent = udev_device_get_parent(device);
210218 if (parent) {
211 kDebug() << "got" << name << "for serial" << id;
212 name = QString::fromAscii(
213 udev_device_get_property_value(parent, "NAME"));
219 kDebug() << "found" << name << "for serial" << id;
220 QByteArray name = udev_device_get_property_value(
221 parent, "NAME");
222 // cache the name
223 d->productNameCache.insert(serial, name);
224 return QString::fromAscii(name);
214225 }
215226 }
216 return name;
227 return QString();
217228}
218229
219230#include "moc_mousedevicesmonitor.cpp"