stats: fix race conditions in vpp-api stats client 97/32897/4
authorArthur de Kerhor <arthurdekerhor@gmail.com>
Thu, 24 Jun 2021 17:39:44 +0000 (19:39 +0200)
committerDave Wallace <dwallacelf@gmail.com>
Fri, 25 Jun 2021 01:04:16 +0000 (01:04 +0000)
Type: fix

Signed-off-by: Arthur de Kerhor <arthurdekerhor@gmail.com>
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Change-Id: Ie5c197f6ec0d41d5e405b22662701d83ad94d29e

src/vpp-api/python/vpp_papi/vpp_stats.py

index 884a300..b407b56 100755 (executable)
@@ -187,12 +187,12 @@ class VPPStats():
         while True:
             try:
                 with self.lock:
+                    self.last_epoch = self.epoch
                     for i, direntry in enumerate(StatsVector(self, self.directory_vector, self.elementfmt)):
                         path_raw = direntry[2].find(b'\x00')
                         path = direntry[2][:path_raw].decode('ascii')
                         directory[path] = StatsEntry(direntry[0], direntry[1])
                         directory_by_idx[i] = path
-                    self.last_epoch = self.epoch
                     self.directory = directory
                     self.directory_by_idx = directory_by_idx
 
@@ -200,7 +200,9 @@ class VPPStats():
                     self.error_vectors = []
                     for threads in StatsVector(self, self.error_vector, 'P'):
                         self.error_vectors.append(StatsVector(self, threads[0], 'Q'))
-                    return
+                # Return statement must be outside the lock block to be sure
+                # lock.release is executed
+                return
             except IOError:
                 if not blocking:
                     raise
@@ -213,7 +215,10 @@ class VPPStats():
                 if self.last_epoch != self.epoch:
                     self.refresh(blocking)
                 with self.lock:
-                    return self.directory[item].get_counter(self)
+                    result = self.directory[item].get_counter(self)
+                # Return statement must be outside the lock block to be sure
+                # lock.release is executed
+                return result
             except IOError:
                 if not blocking:
                     raise
@@ -267,7 +272,10 @@ class VPPStats():
                     if self.last_epoch != self.epoch:
                         self.refresh(blocking)
                     with self.lock:
-                        return sum(self.directory[name].get_counter(self))
+                        result =  sum(self.directory[name].get_counter(self))
+                    # Return statement must be outside the lock block to be sure
+                    # lock.release is executed
+                    return result
                 except IOError:
                     if not blocking:
                         raise