Skip to content

Commit f2a2e2a

Browse files
committed
Added --thread_safe commandline option to webidl_binder.py
This emits all temporaries as 'static thread_local <type> temp;' instead of 'static <type> temp;' and prevents race conditions when you use the resulting library in a multithreaded environment.
1 parent 10cb9d4 commit f2a2e2a

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

tools/webidl_binder.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def getExtendedAttribute(self, _name):
5959
parser = argparse.ArgumentParser()
6060
parser.add_argument('--wasm64', action='store_true', default=False,
6161
help='Build for wasm64')
62+
parser.add_argument('--thread-safe', action='store_true', default=False,
63+
help='Emit temporaries as "static thread_local" to avoid race conditions')
6264
parser.add_argument('infile')
6365
parser.add_argument('outfile')
6466
options = parser.parse_args()
@@ -388,7 +390,7 @@ def type_to_cdec(raw):
388390

389391
def render_function(class_name, func_name, sigs, return_type, non_pointer,
390392
copy, operator, constructor, is_static, func_scope,
391-
call_content=None, const=False, array_attribute=False):
393+
call_content=None, const=False, array_attribute=False, thread_safe=False):
392394
legacy_mode = CHECKS not in ['ALL', 'FAST']
393395
all_checks = CHECKS == 'ALL'
394396

@@ -626,10 +628,13 @@ def make_call_args(i):
626628
basic_return = 'return ' if constructor or return_type != 'Void' else ''
627629
return_prefix = basic_return
628630
return_postfix = ''
631+
storage_attribute = ''
629632
if non_pointer:
630633
return_prefix += '&'
634+
if thread_safe:
635+
storage_attribute = 'thread_local '
631636
if copy:
632-
pre += ' static %s temp;\n' % type_to_c(return_type, non_pointing=True)
637+
pre += ' static %s%s temp;\n' % (storage_attribute, type_to_c(return_type, non_pointing=True))
633638
return_prefix += '(temp = '
634639
return_postfix += ', &temp)'
635640

@@ -767,7 +772,8 @@ def add_bounds_check_impl():
767772
constructor,
768773
is_static=m.isStatic(),
769774
func_scope=m.parentScope.identifier.name,
770-
const=m.getExtendedAttribute('Const'))
775+
const=m.getExtendedAttribute('Const'),
776+
thread_safe=options.thread_safe)
771777
mid_js += ['\n']
772778
if constructor:
773779
mid_js += build_constructor(name)
@@ -809,7 +815,8 @@ def add_bounds_check_impl():
809815
func_scope=interface,
810816
call_content=get_call_content,
811817
const=m.getExtendedAttribute('Const'),
812-
array_attribute=m.type.isArray())
818+
array_attribute=m.type.isArray(),
819+
thread_safe=options.thread_safe)
813820

814821
if m.readonly:
815822
mid_js += [r'''
@@ -831,7 +838,8 @@ def add_bounds_check_impl():
831838
func_scope=interface,
832839
call_content=set_call_content,
833840
const=m.getExtendedAttribute('Const'),
834-
array_attribute=m.type.isArray())
841+
array_attribute=m.type.isArray(),
842+
thread_safe=options.thread_safe)
835843
mid_js += [r'''
836844
/** @suppress {checkTypes} */
837845
Object.defineProperty(%s.prototype, '%s', { get: %s.prototype.%s, set: %s.prototype.%s });
@@ -849,7 +857,8 @@ def add_bounds_check_impl():
849857
False,
850858
False,
851859
func_scope=interface,
852-
call_content='delete self')
860+
call_content='delete self',
861+
thread_safe=options.thread_safe)
853862

854863
# Emit C++ class implementation that calls into JS implementation
855864

0 commit comments

Comments
 (0)