44import itertools
55import sys
66import textwrap
7+ import threading
78from dataclasses import replace
8- from functools import partial
9+ from functools import partial , wraps
910from types import FunctionType
1011
1112from .recode import (
@@ -43,6 +44,15 @@ def _getdoc(fn):
4344_current_id = itertools .count ()
4445
4546
47+ def locked (fn ):
48+ @wraps (fn )
49+ def wrapper (self , * args , ** kwargs ):
50+ with self ._mutex :
51+ return fn (self , * args , ** kwargs )
52+
53+ return wrapper
54+
55+
4656def bootstrap_dispatch (ov , name ):
4757 def first_entry (* args , ** kwargs ):
4858 ov .compile ()
@@ -111,6 +121,7 @@ def __init__(
111121 self ._locked = False
112122 self .mixins = []
113123 self .dispatch = bootstrap_dispatch (self , name = self .shortname )
124+ self ._mutex = threading .Lock ()
114125 self .add_mixins (* mixins )
115126
116127 def regs (self ):
@@ -239,6 +250,7 @@ def argument_analysis(self):
239250 self ._argument_analysis = aa
240251 return self ._argument_analysis
241252
253+ @locked
242254 def compile (self ):
243255 """Finalize this overload.
244256
@@ -249,6 +261,11 @@ def compile(self):
249261 This will also lock this ovld's parent mixins to prevent their
250262 modification.
251263 """
264+ if self ._compiled : # pragma: no cover
265+ return
266+
267+ self ._compiled = False
268+
252269 for mixin in self .mixins :
253270 if self not in mixin .children :
254271 mixin .lock ()
0 commit comments