From: Adrian Freihofer <[email protected]>

SystemStats.close() is normally invoked by the buildstats.bbclass handler
on bb.event.BuildCompleted, but that event is skipped for internal,
event-less task runs (e.g. tinfoil's run_prepared_task(), used by
devtool ide-sdk). Without a BuildCompleted event, the open proc/disk log
files were only closed implicitly at GC/interpreter-exit time, causing a
ResourceWarning for leaked file handles.

Register a weakref.finalize() callback at construction time as a safety
net. close() now just triggers the finalizer, which is idempotent and
keeps no reference back to SystemStats itself.

AI-Generated: Uses GitHub Copilot

Signed-off-by: Adrian Freihofer <[email protected]>
---
 meta/lib/oe/buildstats.py | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/meta/lib/oe/buildstats.py b/meta/lib/oe/buildstats.py
index db3d26afb8..56228246e4 100644
--- a/meta/lib/oe/buildstats.py
+++ b/meta/lib/oe/buildstats.py
@@ -10,6 +10,7 @@
 import os
 import time
 import re
+import weakref
 import bb.event
 from collections import deque
 
@@ -56,6 +57,12 @@ class SystemStats:
                     destfile = os.path.join(bsdir, '%sproc_%s.log' % 
('reduced_' if handler else '', filename))
                 self.proc_files.append((filename, open(destfile, 'ab'), 
handler))
         self.monitor_disk = open(os.path.join(bsdir, 'monitor_disk.log'), 'ab')
+        # Safety net: normally close() is called when bb.event.BuildCompleted
+        # fires, but that event is skipped for internal, event-less task runs
+        # (e.g. tinfoil's run_prepared_task()). Without this, the open files
+        # would only get closed implicitly at GC/interpreter-exit time,
+        # triggering a ResourceWarning.
+        self._finalizer = weakref.finalize(self, self._close_files, 
self.proc_files, self.monitor_disk)
         # Last time that we sampled /proc data resp. recorded disk monitoring 
data.
         self.last_proc = 0
         self.last_disk_monitor = 0
@@ -81,8 +88,12 @@ class SystemStats:
         self.net_stats = {}
 
     def close(self):
-        self.monitor_disk.close()
-        for _, output, _ in self.proc_files:
+        self._finalizer()
+
+    @staticmethod
+    def _close_files(proc_files, monitor_disk):
+        monitor_disk.close()
+        for _, output, _ in proc_files:
             output.close()
 
     def _reduce_meminfo(self, time, data, filename):
-- 
2.55.0

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#245517): 
https://lists.openembedded.org/g/openembedded-core/message/245517
Mute This Topic: https://lists.openembedded.org/mt/121171413/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to