File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1264,12 +1264,20 @@ def is_opentype_cff_font(filename):
12641264 return False
12651265
12661266
1267- _get_font = lru_cache (64 )(ft2font .FT2Font )
12681267_fmcache = os .path .join (
12691268 mpl .get_cachedir (), 'fontlist-v{}.json' .format (FontManager .__version__ ))
12701269fontManager = None
12711270
12721271
1272+ _get_font = lru_cache (64 )(ft2font .FT2Font )
1273+ # FT2Font objects cannot be used across fork()s because they reference the same
1274+ # FT_Library object. While invalidating *all* existing FT2Fonts after a fork
1275+ # would be too complicated to be worth it, the main way FT2Fonts get reused is
1276+ # via the cache of _get_font, which we can empty upon forking (in Py3.7+).
1277+ if hasattr (os , "register_at_fork" ):
1278+ os .register_at_fork (after_in_child = _get_font .cache_clear )
1279+
1280+
12731281def get_font (filename , hinting_factor = None ):
12741282 if hinting_factor is None :
12751283 hinting_factor = rcParams ['text.hinting_factor' ]
Original file line number Diff line number Diff line change 11from io import BytesIO
2+ import multiprocessing
23import os
34from pathlib import Path
45import shutil
@@ -184,3 +185,17 @@ def test_user_fonts_win32():
184185 # Now, the font should be available
185186 fonts = findSystemFonts ()
186187 assert any (font_test_file in font for font in fonts )
188+
189+
190+ def _model_handler (_ ):
191+ fig , ax = plt .subplots ()
192+ fig .savefig (BytesIO (), format = "pdf" )
193+ plt .close ()
194+
195+
196+ @pytest .mark .skipif (not hasattr (os , "register_at_fork" ),
197+ reason = "Cannot register at_fork handlers" )
198+ def test_fork ():
199+ _model_handler (0 ) # Make sure the font cache is filled.
200+ ctx = multiprocessing .get_context ("fork" )
201+ ctx .Pool (processes = 2 ).map (_model_handler , range (2 ))
You can’t perform that action at this time.
0 commit comments