Skip to content

Commit cfe9c58

Browse files
committed
Use atexit to add another layer of protection
Hopefully should make process leaks vanishingly rare. Basically only on crashes.
1 parent f82da06 commit cfe9c58

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

src/calibre/scraper/qt.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#!/usr/bin/env python
22
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
33

4+
import atexit
45
import json
56
import os
67
import shutil
78
import subprocess
8-
import time
9+
import weakref
910
from contextlib import suppress
1011
from io import BytesIO
1112
from queue import Queue
@@ -101,6 +102,12 @@ def close(self):
101102
self._data.close()
102103

103104

105+
def shutdown_browser(bref):
106+
br = bref()
107+
if br is not None:
108+
br.shutdown()
109+
110+
104111
class Browser:
105112

106113
def __init__(self, user_agent: str = '', headers: tuple[tuple[str, str], ...] = (), verify_ssl_certificates: bool = True, start_worker: bool = False):
@@ -113,6 +120,7 @@ def __init__(self, user_agent: str = '', headers: tuple[tuple[str, str], ...] =
113120
self.user_agent = user_agent
114121
self.lock = RLock()
115122
self.shutting_down = False
123+
atexit.register(shutdown_browser, weakref.ref(self))
116124
if start_worker:
117125
self._ensure_state()
118126

@@ -226,16 +234,18 @@ def _dispatch(self):
226234
def shutdown(self):
227235
self.shutting_down = True
228236
import shutil
237+
import time
229238
if self.worker:
239+
w, self.worker = self.worker, None
230240
with suppress(OSError):
231-
self.worker.stdin.close()
241+
w.stdin.close()
232242
with suppress(OSError):
233-
self.worker.stdout.close()
243+
w.stdout.close()
234244
give_up_at = time.monotonic() + 1.5
235-
while time.monotonic() < give_up_at and self.worker.poll() is None:
245+
while time.monotonic() < give_up_at and w.poll() is None:
236246
time.sleep(0.01)
237-
if self.worker.poll() is None:
238-
self.worker.kill()
247+
if w.poll() is None:
248+
w.kill()
239249
if self.tdir:
240250
with suppress(OSError):
241251
shutil.rmtree(self.tdir)

0 commit comments

Comments
 (0)