Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0efc44c

Browse files
committed
Avoid need to lock in dvi generation, to avoid deadlocks.
Instead, generate the dvi in a temporary directory and move it to its final path.
1 parent 8c2fbda commit 0efc44c

1 file changed

Lines changed: 13 additions & 13 deletions

File tree

lib/matplotlib/texmanager.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from pathlib import Path
3636
import re
3737
import subprocess
38+
from tempfile import TemporaryDirectory
3839

3940
import numpy as np
4041

@@ -269,12 +270,12 @@ def make_tex_preview(self, tex, fontsize):
269270

270271
return texfile
271272

272-
def _run_checked_subprocess(self, command, tex):
273+
def _run_checked_subprocess(self, command, tex, *, cwd=None):
273274
_log.debug(cbook._pformat_subprocess(command))
274275
try:
275-
report = subprocess.check_output(command,
276-
cwd=self.texcache,
277-
stderr=subprocess.STDOUT)
276+
report = subprocess.check_output(
277+
command, cwd=cwd if cwd is not None else self.texcache,
278+
stderr=subprocess.STDOUT)
278279
except FileNotFoundError as exc:
279280
raise RuntimeError(
280281
'Failed to process string with tex because {} could not be '
@@ -305,17 +306,16 @@ def make_dvi(self, tex, fontsize):
305306
dvifile = '%s.dvi' % basefile
306307
if not os.path.exists(dvifile):
307308
texfile = self.make_tex(tex, fontsize)
308-
with cbook._lock_path(texfile):
309+
# Generate the dvi in a temporary directory to avoid race
310+
# conditions e.g. if multiple processes try to process the same tex
311+
# string at the same time. Having tmpdir be a subdirectory of the
312+
# final output dir ensures that they are on the same filesystem,
313+
# and thus replace() works atomically.
314+
with TemporaryDirectory(dir=Path(dvifile).parent) as tmpdir:
309315
self._run_checked_subprocess(
310316
["latex", "-interaction=nonstopmode", "--halt-on-error",
311-
texfile], tex)
312-
for fname in glob.glob(basefile + '*'):
313-
if not fname.endswith(('dvi', 'tex')):
314-
try:
315-
os.remove(fname)
316-
except OSError:
317-
pass
318-
317+
texfile], tex, cwd=tmpdir)
318+
(Path(tmpdir) / Path(dvifile).name).replace(dvifile)
319319
return dvifile
320320

321321
@cbook.deprecated("3.3")

0 commit comments

Comments
 (0)