Fix python map.items() racing with bpf delete
authorBrenden Blanco <bblanco@plumgrid.com>
Sun, 7 Feb 2016 14:57:17 +0000 (06:57 -0800)
committerBrenden Blanco <bblanco@plumgrid.com>
Sun, 7 Feb 2016 14:57:17 +0000 (06:57 -0800)
The default python implementation of itervalues(), iteritems(), items(), and
values() do a sequence of iter().next followed by self[key], which may
produce a KeyError since a bpf program can delete them quickly. It
should be safe to suppress such errors, hiding them from the user.

Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
src/python/bcc/__init__.py

index 843a6d8..8c1ef59 100644 (file)
@@ -286,6 +286,30 @@ class BPF(object):
                 if res < 0:
                     raise KeyError
 
+        # override the MutableMapping's implementation of these since they
+        # don't handle KeyError nicely
+        def itervalues(self):
+            for key in self:
+                # a map entry may be deleted in between discovering the key and
+                # fetching the value, suppress such errors
+                try:
+                    yield self[key]
+                except KeyError:
+                    pass
+
+        def iteritems(self):
+            for key in self:
+                try:
+                    yield (key, self[key])
+                except KeyError:
+                    pass
+
+        def items(self):
+            return [item for item in self.iteritems()]
+
+        def values(self):
+            return [value for value in self.itervalues()]
+
         def clear(self):
             # default clear uses popitem, which can race with the bpf prog
             for k in self.keys():