r9y9 / pyopenjtalk

Python wrapper for OpenJTalk
https://r9y9.github.io/pyopenjtalk/
Other
203 stars 70 forks source link

`pyopenjtalk.synthesize()` is not thread safe. #86

Open sabonerune opened 4 weeks ago

sabonerune commented 4 weeks ago

The following code causes a segmentation fault:

from concurrent.futures import ThreadPoolExecutor

import pyopenjtalk

label = pyopenjtalk.extract_fullcontext(text)
with ThreadPoolExecutor() as e:
    futures = [e.submit(ojt.synthesize, label) for i in range(32)]
results = [i.result() for i in futures]
first = results[0]
for i, j in results[1:-1]:
    assert np.allclose(first[0], i)
    assert first[1] == j
print("synthesize() done")

To prevent this, a mutex is required for the functions that accesses _global_htsengine.

There should also be mutexes for other global objects.

NOTE: This problem becomes worse if we add code that releases the GIL.