mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Use atexit to add another layer of protection
Hopefully should make process leaks vanishingly rare. Basically only on crashes.
This commit is contained in:
parent
f82da06184
commit
cfe9c58db8
@ -1,11 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import atexit
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import weakref
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
@ -101,6 +102,12 @@ class FakeResponse:
|
|||||||
self._data.close()
|
self._data.close()
|
||||||
|
|
||||||
|
|
||||||
|
def shutdown_browser(bref):
|
||||||
|
br = bref()
|
||||||
|
if br is not None:
|
||||||
|
br.shutdown()
|
||||||
|
|
||||||
|
|
||||||
class Browser:
|
class Browser:
|
||||||
|
|
||||||
def __init__(self, user_agent: str = '', headers: tuple[tuple[str, str], ...] = (), verify_ssl_certificates: bool = True, start_worker: bool = False):
|
def __init__(self, user_agent: str = '', headers: tuple[tuple[str, str], ...] = (), verify_ssl_certificates: bool = True, start_worker: bool = False):
|
||||||
@ -113,6 +120,7 @@ class Browser:
|
|||||||
self.user_agent = user_agent
|
self.user_agent = user_agent
|
||||||
self.lock = RLock()
|
self.lock = RLock()
|
||||||
self.shutting_down = False
|
self.shutting_down = False
|
||||||
|
atexit.register(shutdown_browser, weakref.ref(self))
|
||||||
if start_worker:
|
if start_worker:
|
||||||
self._ensure_state()
|
self._ensure_state()
|
||||||
|
|
||||||
@ -226,16 +234,18 @@ class Browser:
|
|||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
self.shutting_down = True
|
self.shutting_down = True
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
if self.worker:
|
if self.worker:
|
||||||
|
w, self.worker = self.worker, None
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
self.worker.stdin.close()
|
w.stdin.close()
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
self.worker.stdout.close()
|
w.stdout.close()
|
||||||
give_up_at = time.monotonic() + 1.5
|
give_up_at = time.monotonic() + 1.5
|
||||||
while time.monotonic() < give_up_at and self.worker.poll() is None:
|
while time.monotonic() < give_up_at and w.poll() is None:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
if self.worker.poll() is None:
|
if w.poll() is None:
|
||||||
self.worker.kill()
|
w.kill()
|
||||||
if self.tdir:
|
if self.tdir:
|
||||||
with suppress(OSError):
|
with suppress(OSError):
|
||||||
shutil.rmtree(self.tdir)
|
shutil.rmtree(self.tdir)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user